CVE-2021-21681
Description
Jenkins Nomad Plugin <=0.7.4 stores Docker passwords unencrypted in global config.xml.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jenkins Nomad Plugin <=0.7.4 stores Docker passwords unencrypted in global config.xml.
Vulnerability
Jenkins Nomad Plugin version 0.7.4 and earlier stores Docker passwords in plaintext in the global config.xml file on the Jenkins controller [1][2]. The password field is not masked or encrypted, making it readable by anyone with file system access to the controller.
Exploitation
An attacker who can read the Jenkins controller's file system (e.g., an authenticated Jenkins administrator or a user who has compromised a controller node) can navigate to the $JENKINS_HOME/config.xml file and retrieve the Docker password stored in plaintext [1]. No special authentication beyond file system access is required.
Impact
Successful exploitation results in disclosure of the Docker password, which could be used to access the Docker registry or other services that rely on those credentials, potentially leading to further compromise of the CI/CD infrastructure [1][2].
Mitigation
Jenkins Nomad Plugin version 0.7.5, released on 2021-08-31, fixes the issue by storing the password using Jenkins' Secret class (which encrypts the value at rest) [2][3][4]. Users should upgrade to version 0.7.5 or later. There is no known workaround if the plugin cannot be upgraded.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jenkins-ci.plugins:nomadMaven | < 0.7.5 | 0.7.5 |
Affected products
2- Range: unspecified
Patches
1d45123487d57SECURITY-2396
3 files changed · +8 −6
src/main/java/org/jenkinsci/plugins/nomad/NomadApi.java+1 −1 modified@@ -116,7 +116,7 @@ private Map<String, Object> buildDriverConfig(String name, String secret, NomadC if (template.getUsername() != null && !template.getUsername().isEmpty()) { Map<String, String> authConfig = new HashMap<>(); authConfig.put("username", template.getUsername()); - authConfig.put("password", template.getPassword()); + authConfig.put("password", template.getPassword().getPlainText()); ArrayList<Map> credentials = new ArrayList<>(); credentials.add(authConfig);
src/main/java/org/jenkinsci/plugins/nomad/NomadWorkerTemplate.java+4 −3 modified@@ -7,6 +7,7 @@ import hudson.model.Label; import hudson.model.Node; import hudson.model.labels.LabelAtom; +import hudson.util.Secret; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.DataBoundConstructor; @@ -39,7 +40,7 @@ public class NomadWorkerTemplate implements Describable<NomadWorkerTemplate> { private final Boolean privileged; private final String network; private final String username; - private final String password; + private final Secret password; private final String prefixCmd; private final Boolean forcePull; private final String hostVolumes; @@ -76,7 +77,7 @@ public NomadWorkerTemplate( String image, String datacenters, String username, - String password, + Secret password, Boolean privileged, String network, String prefixCmd, @@ -239,7 +240,7 @@ public String getUsername() { return username; } - public String getPassword() { + public Secret getPassword() { return password; }
src/test/java/org/jenkinsci/plugins/nomad/NomadApiTest.java+3 −2 modified@@ -1,6 +1,7 @@ package org.jenkinsci.plugins.nomad; import hudson.model.Node; +import hudson.util.Secret; import org.junit.Test; import java.util.Arrays; @@ -24,7 +25,7 @@ public class NomadApiTest { private final NomadWorkerTemplate workerTemplate = new NomadWorkerTemplate( "test", "300", "256", "100", null, constraintTest, "remoteFs", false, "3", true, "1", Node.Mode.NORMAL, - "ams", "0", "image", "dc01", "", "", false, "bridge", + "ams", "0", "image", "dc01", "", Secret.fromString(""), false, "bridge", "", true, "/mnt:/mnt", "jenkins", new ArrayList<NomadPortTemplate>() { }, "my_host:192.168.1.1,", "8.8.8.8,1.1.1.1", "apparmor=unconfined, seccomp=unconfined", "SYS_ADMIN, SYSLOG", "SYS_ADMIN, SYSLOG", "policy1,policy2", devicePluginsTest @@ -63,7 +64,7 @@ public void testStartWorker() { private final NomadWorkerTemplate nullTemplate = new NomadWorkerTemplate( "test", "300", "256", "100", null, constraintTest, "remoteFs", false, "3", true, "1", Node.Mode.NORMAL, - "ams", "0", "image", "dc01", "", "", false, "bridge", + "ams", "0", "image", "dc01", "", Secret.fromString(""), false, "bridge", "", true, "/mnt:/mnt", "jenkins", new ArrayList<NomadPortTemplate>() { }, "my_host:192.168.1.1,", "8.8.8.8,1.1.1.1", "apparmor=unconfined, seccomp=unconfined", "SYS_ADMIN, SYSLOG", "SYS_ADMIN, SYSLOG", null, devicePluginsTest
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-5c2c-cvg6-ghjmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-21681ghsaADVISORY
- www.openwall.com/lists/oss-security/2021/08/31/1ghsamailing-listx_refsource_MLISTWEB
- github.com/jenkinsci/nomad-plugin/commit/d45123487d57c0e2a8a6869866b05362f690f511ghsaWEB
- www.jenkins.io/security/advisory/2021-08-31/ghsax_refsource_CONFIRMWEB
News mentions
1- Jenkins Security Advisory 2021-08-31Jenkins Security Advisories · Aug 31, 2021