diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 6c4377652a..88c21defed 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -1715,7 +1715,16 @@ public class Functions { */ public String getPasswordValue(Object o) { if (o==null) return null; - if (o instanceof Secret) return ((Secret)o).getEncryptedValue(); + if (o instanceof Secret) { + StaplerRequest req = Stapler.getCurrentRequest(); + if (req != null) { + Item item = req.findAncestorObject(Item.class); + if (item != null && !item.hasPermission(Item.CONFIGURE)) { + return ""; + } + } + return ((Secret) o).getEncryptedValue(); + } if (getIsUnitTest()) { throw new SecurityException("attempted to render plaintext ‘" + o + "’ in password field; use a getter of type Secret instead"); } diff --git a/test/src/test/java/lib/form/PasswordTest.java b/test/src/test/java/lib/form/PasswordTest.java index 030c38f504..e4e103cc4b 100644 --- a/test/src/test/java/lib/form/PasswordTest.java +++ b/test/src/test/java/lib/form/PasswordTest.java @@ -28,8 +28,20 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage; import hudson.Extension; import hudson.model.Describable; import hudson.model.Descriptor; +import hudson.model.FreeStyleProject; +import hudson.model.Item; +import hudson.model.JobProperty; +import hudson.model.JobPropertyDescriptor; +import hudson.security.GlobalMatrixAuthorizationStrategy; import hudson.util.Secret; +import jenkins.model.Jenkins; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; import org.jvnet.hudson.test.HudsonTestCase; +import org.jvnet.hudson.test.Issue; +import org.jvnet.hudson.test.TestExtension; +import org.kohsuke.stapler.DataBoundConstructor; /** * @author Kohsuke Kawaguchi @@ -55,4 +67,51 @@ public class PasswordTest extends HudsonTestCase implements Describable { + public final Secret secret; + @DataBoundConstructor + public VulnerableProperty(Secret secret) { + this.secret = secret; + } + @TestExtension("testExposedCiphertext") + public static class DescriptorImpl extends JobPropertyDescriptor { + @Override // TODO delete in 1.635+ + public String getDisplayName() { + return "VulnerableProperty"; + } + } + } + } diff --git a/test/src/test/resources/lib/form/PasswordTest/VulnerableProperty/config.jelly b/test/src/test/resources/lib/form/PasswordTest/VulnerableProperty/config.jelly new file mode 100644 index 0000000000..0de0f24317 --- /dev/null +++ b/test/src/test/resources/lib/form/PasswordTest/VulnerableProperty/config.jelly @@ -0,0 +1,31 @@ + + + + + + + + +