VYPR
Moderate severityNVD Advisory· Published Feb 9, 2018· Updated Aug 5, 2024

CVE-2018-1000057

CVE-2018-1000057

Description

Jenkins Credentials Binding Plugin 1.14 and earlier fails to mask passwords that are transformed by environment variable expansion, allowing disclosure in build logs.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Jenkins Credentials Binding Plugin 1.14 and earlier fails to mask passwords that are transformed by environment variable expansion, allowing disclosure in build logs.

Vulnerability

The Jenkins Credentials Binding Plugin versions 1.14 and earlier [1][3] masks passwords it provides to build processes in their build logs. However, Jenkins transforms provided password values before passing them to builds, for example by replacing environment variable references [1]. This transformation can produce values that differ from but are similar to the configured password, such as when a password contains $$ which Jenkins resolves to $. The transformed value is not subject to masking, potentially exposing the original password to unauthorized users [1][3].

Exploitation

An attacker needs access to build logs in Jenkins, such as a user with read access to build console output [1]. The vulnerability occurs when a configured password contains a sequence like $$ (the escape for a single $). Jenkins transforms this to $ before passing it to the build, and the transformed value (e.g., p4$w0rd instead of p4$$w0rd) is not masked in the build log [3]. An attacker viewing the log can see the transformed value and reconstruct the original password [1][3].

Impact

A successful attacker can recover the original password value from the visible transformed value in build logs [1][3]. This leads to unauthorized disclosure of sensitive credentials, compromising the confidentiality of the password. The attacker does not need elevated privileges beyond read access to build logs to exploit this issue [1].

Mitigation

Credentials Binding Plugin version 1.15, released on 2018-02-05, fixes the issue by escaping $ characters in password values so they are correctly passed to the build without transformation [2][3]. Users should upgrade to version 1.15 or later. No workaround is described in the available references [1][2][3].

AI Insight generated on May 22, 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.

PackageAffected versionsPatched versions
org.jenkins-ci.plugins:credentials-bindingMaven
< 1.151.15

Affected products

1

Patches

1
0c7523893336

[SECURITY-698] SecretBuildWrapper must double up $ twice to undo what Jenkins would otherwise expand.

4 files changed · +16 8
  • pom.xml+6 0 modified
    @@ -96,6 +96,12 @@
           <version>2.5</version>
           <scope>test</scope>
         </dependency>
    +    <dependency>
    +      <groupId>org.jenkins-ci.plugins</groupId>
    +      <artifactId>durable-task</artifactId>
    +      <version>1.13</version>
    +      <scope>test</scope>
    +    </dependency>
         <dependency>
           <groupId>org.jenkins-ci.plugins.workflow</groupId>
           <artifactId>workflow-basic-steps</artifactId>
    
  • src/main/java/org/jenkinsci/plugins/credentialsbinding/impl/SecretBuildWrapper.java+3 1 modified
    @@ -97,7 +97,9 @@ public OutputStream decorateLogger(AbstractBuild build, OutputStream logger) thr
             return new Environment() {
                 @Override public void buildEnvVars(Map<String,String> env) {
                     for (MultiBinding.MultiEnvironment e : m) {
    -                    env.putAll(e.getValues());
    +                    for (Map.Entry<String,String> pair : e.getValues().entrySet()) {
    +                        env.put(pair.getKey(), pair.getValue()./* SECURITY-698 */replace("$", "$$$$"));
    +                    }
                     }
                 }
                 @Override public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException {
    
  • src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BindingStepTest.java+2 2 modified
    @@ -126,7 +126,7 @@ public static class Execution extends AbstractSynchronousStepExecution<Void> {
         @Test public void basics() throws Exception {
             final String credentialsId = "creds";
             final String username = "bob";
    -        final String password = "s3cr3t";
    +        final String password = "s$$cr3t";
             story.addStep(new Statement() {
                 @Override public void evaluate() throws Throwable {
                     UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", username, password);
    @@ -137,7 +137,7 @@ public static class Execution extends AbstractSynchronousStepExecution<Void> {
                             + "  withCredentials([usernamePassword(usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD', credentialsId: '" + credentialsId + "')]) {\n"
                             + "    semaphore 'basics'\n"
                             + "    if (isUnix()) {\n"
    -                        + "      sh 'echo curl -u $USERNAME:$PASSWORD server > script'\n"
    +                        + "      sh 'echo curl -u \"$USERNAME:$PASSWORD\" server > script'\n"
                             + "    } else {\n"
                             + "      bat 'echo curl -u %USERNAME%:%PASSWORD% server > script'\n"
                             + "    }\n"
    
  • src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SecretBuildWrapperTest.java+5 5 modified
    @@ -55,13 +55,13 @@ public class SecretBuildWrapperTest {
         @Issue("JENKINS-24805")
         @Test public void maskingFreeStyleSecrets() throws Exception {
             String firstCredentialsId = "creds_1";
    -        String firstPassword = "p4ss";
    +        String firstPassword = "p4$$";
             StringCredentialsImpl firstCreds = new StringCredentialsImpl(CredentialsScope.GLOBAL, firstCredentialsId, "sample1", Secret.fromString(firstPassword));
     
             CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), firstCreds);
     
             String secondCredentialsId = "creds_2";
    -        String secondPassword = "p4ss" + "someMoreStuff";
    +        String secondPassword = "p4$$" + "someMoreStuff";
             StringCredentialsImpl secondCreds = new StringCredentialsImpl(CredentialsScope.GLOBAL, secondCredentialsId, "sample2", Secret.fromString(secondPassword));
     
             CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), secondCreds);
    @@ -72,16 +72,16 @@ public class SecretBuildWrapperTest {
             FreeStyleProject f = r.createFreeStyleProject();
     
             f.setConcurrentBuild(true);
    -        f.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo %PASS_1%") : new Shell("echo $PASS_1"));
    -        f.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo %PASS_2%") : new Shell("echo $PASS_2"));
    +        f.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo %PASS_1%") : new Shell("echo \"$PASS_1\""));
    +        f.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo %PASS_2%") : new Shell("echo \"$PASS_2\""));
             f.getBuildWrappersList().add(wrapper);
     
             r.configRoundtrip((Item)f);
     
             FreeStyleBuild b = r.buildAndAssertSuccess(f);
             r.assertLogNotContains(firstPassword, b);
             r.assertLogNotContains(secondPassword, b);
    -        r.assertLogContains("echo ****", b);
    +        r.assertLogContains("****", b);
         }
     
         @Issue("JENKINS-24805")
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.