CVE-2020-2181
Description
Jenkins Credentials Binding Plugin 1.22 and earlier fails to mask secrets in build logs when no build steps exist, potentially exposing sensitive credentials.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jenkins Credentials Binding Plugin 1.22 and earlier fails to mask secrets in build logs when no build steps exist, potentially exposing sensitive credentials.
The Jenkins Credentials Binding Plugin is used to inject secrets such as passwords and API tokens as environment variables into builds. In versions 1.22 and earlier, there is a logic flaw where secrets are not masked (i.e., not replaced with asterisks) in the build log when the build contains no build steps [1][2]. This means that if a build is configured with credentials binding but executes no actual build steps (e.g., only runs post-build actions), the secrets appear in plaintext in the console output.
Exploitation requires the ability to create or configure a Jenkins job that uses credentials binding and has no build steps. An attacker with Job/Configure permission can set up such a job to expose credentials. Alternatively, if a legitimate job is misconfigured to have no build steps, secrets may be leaked to any user with Job/Read permission to view the build log [1]. The vulnerability is triggered simply by running the build; no special network position or authentication bypass is needed.
The impact is the exposure of sensitive credentials, which could lead to unauthorized access to external systems managed by Jenkins. The CVSS score is Medium (6.5) per the Jenkins advisory, reflecting the prerequisite of job configuration or misconfiguration [1].
The issue is fixed in Credentials Binding Plugin version 1.23, released on 2020-05-06 [1][4]. Users should upgrade immediately. No workarounds are available. The fix ensures that secrets are masked even when no build steps are present.
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:credentials-bindingMaven | < 1.23 | 1.23 |
Affected products
2- Range: unspecified
Patches
159ead11bcb3f[SECURITY-1374]
2 files changed · +49 −1
src/main/java/org/jenkinsci/plugins/credentialsbinding/impl/SecretBuildWrapper.java+1 −1 modified@@ -107,7 +107,6 @@ public OutputStream decorateLogger(AbstractBuild build, OutputStream logger) thr for (MultiBinding.MultiEnvironment e : m) { e.getUnbinder().unbind(build, build.getWorkspace(), launcher, listener); } - secretsForBuild.remove(build); return true; } }; @@ -165,6 +164,7 @@ private static final class Filter extends ConsoleLogFilter { @Override public void close() throws IOException { super.close(); logger.close(); + secretsForBuild.remove(build); } }; }
src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SecretBuildWrapperTest.java+48 −0 modified@@ -28,10 +28,16 @@ import com.cloudbees.plugins.credentials.CredentialsScope; import com.cloudbees.plugins.credentials.domains.Domain; import hudson.Functions; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.BuildListener; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.Item; import hudson.tasks.BatchFile; +import hudson.tasks.BuildStepMonitor; +import hudson.tasks.Publisher; +import hudson.tasks.Recorder; import hudson.tasks.Shell; import hudson.util.Secret; import org.jenkinsci.plugins.credentialsbinding.MultiBinding; @@ -109,4 +115,46 @@ public class SecretBuildWrapperTest { r.assertLogContains("PASSES", r.buildAndAssertSuccess(p)); } + @Issue("SECURITY-1374") + @Test public void maskingPostBuild() throws Exception { + String credentialsId = "creds_1"; + String password = "p4$$"; + StringCredentialsImpl firstCreds = new StringCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample1", Secret.fromString(password)); + + CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), firstCreds); + + SecretBuildWrapper wrapper = new SecretBuildWrapper(Collections.singletonList(new StringBinding("PASS_1", credentialsId))); + + FreeStyleProject f = r.createFreeStyleProject(); + + f.setConcurrentBuild(true); + f.getBuildWrappersList().add(wrapper); + Publisher publisher = new PasswordPublisher(password); + f.getPublishersList().add(publisher); + + FreeStyleBuild b = r.buildAndAssertSuccess(f); + r.assertLogNotContains(password, b); + r.assertLogContains("****", b); + } + + static class PasswordPublisher extends Recorder { + + private String password; + + public PasswordPublisher(String password) { + this.password = password; + } + + public @Override + boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) { + listener.getLogger().println("Sneak it in during the postbuild: " + password + " :done."); + return true; + } + + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + } + }
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-43j2-r4v3-m8jpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-2181ghsaADVISORY
- www.openwall.com/lists/oss-security/2020/05/06/3ghsamailing-listx_refsource_MLISTWEB
- github.com/jenkinsci/credentials-binding-plugin/commit/59ead11bcb3fd132258d1d7da4a34d47750f40d2ghsaWEB
- jenkins.io/security/advisory/2020-05-06/ghsax_refsource_CONFIRMWEB
News mentions
1- Jenkins Security Advisory 2020-05-06Jenkins Security Advisories · May 6, 2020