VYPR
Moderate severityNVD Advisory· Published Apr 4, 2019· Updated Aug 5, 2024

CVE-2019-1003089

CVE-2019-1003089

Description

Jenkins Upload to pgyer Plugin stores credentials unencrypted in job config.xml files on the Jenkins master where they can be viewed by users with Extended Read permission, or access to the master file system.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
ren.helloworld:upload-pgyerMaven
< 1.331.33

Affected products

1

Patches

1
af4e89754c31

Fixed SECURITY-1044

21 files changed · +77 64
  • pom.xml+9 8 modified
    @@ -1,5 +1,6 @@
     <?xml version="1.0" encoding="UTF-8"?>
    -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    +         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
         <modelVersion>4.0.0</modelVersion>
     
         <properties>
    @@ -10,12 +11,12 @@
             <groupId>org.jenkins-ci.plugins</groupId>
             <artifactId>plugin</artifactId>
             <version>2.11</version>
    -        <relativePath />
    +        <relativePath/>
         </parent>
     
         <groupId>ren.helloworld</groupId>
         <artifactId>upload-pgyer</artifactId>
    -    <version>1.32-SNAPSHOT</version>
    +    <version>1.33-SNAPSHOT</version>
         <packaging>hpi</packaging>
         <name>Upload to pgyer</name>
         <description>Upload to pgyer for jenkins plugin</description>
    @@ -33,14 +34,14 @@
                 <id>myroid</id>
                 <name>fan yang</name>
                 <email>myroid@foxmail.com</email>
    -            <url>http://dafan.tech</url>
    -            <organization>Micute</organization>
    +            <url>https://iamfan.cn</url>
    +            <organization>NetEase</organization>
             </developer>
         </developers>
     
         <organization>
    -        <name>Micute</name>
    -        <url>http://www.91ylian.com/</url>
    +        <name>NetEase</name>
    +        <url>https://www.163.com/</url>
         </organization>
     
         <repositories>
    @@ -67,7 +68,7 @@
             <dependency>
                 <groupId>com.google.code.gson</groupId>
                 <artifactId>gson</artifactId>
    -            <version>2.8.4</version>
    +            <version>2.8.5</version>
             </dependency>
     
             <dependency>
    
  • README_cn.md+5 0 modified
    @@ -82,6 +82,11 @@ appPgyerURL| 应用主页地址
     appBuildURL| 本次上传的应用主页
     
     ### Change Log
    +版本 1.33(2019-09-07)
    +
    +- 修复[SECURITY-1044](https://issues.jenkins-ci.org/browse/SECURITY-1044)
    +- 升级Gson 2.8.5
    +
     版本 1.31(2018-05-07)
     
     - 升级Gson 2.8.4
    
  • README.md+5 0 modified
    @@ -84,6 +84,11 @@ appPgyerURL|Application pgyer url
     appBuildURL|Application build pgyer url
     
     ### Change Log
    +Version 1.33(2019-09-07)
    +
    +- Fixed [SECURITY-1044](https://issues.jenkins-ci.org/browse/SECURITY-1044)
    +- Upgrade gson 2.8.5
    +
     Version 1.31(2018-05-07)
     
     - Upgrade gson 2.8.4
    
  • src/main/java/ren/helloworld/upload2pgyer/UploadBuilder.java+13 16 modified
    @@ -8,6 +8,7 @@
     import hudson.tasks.BuildStepDescriptor;
     import hudson.tasks.Builder;
     import hudson.util.FormValidation;
    +import hudson.util.Secret;
     import org.jenkinsci.Symbol;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.QueryParameter;
    @@ -24,35 +25,35 @@
      */
     public class UploadBuilder extends Builder {
     
    -    private String uKey;
    -    private String apiKey;
    +    private Secret uKey;
    +    private Secret apiKey;
         private String scanDir;
         private String wildcard;
         private String installType;
    -    private String password;
    +    private Secret password;
         private String updateDescription;
     
         private String qrcodePath;
         private String envVarsPath;
     
         @DataBoundConstructor
         public UploadBuilder(String uKey, String apiKey, String scanDir, String wildcard, String installType, String password, String updateDescription, String qrcodePath, String envVarsPath) {
    -        this.uKey = uKey;
    -        this.apiKey = apiKey;
    +        this.uKey = Secret.fromString(uKey);
    +        this.apiKey = Secret.fromString(apiKey);
             this.scanDir = scanDir;
             this.wildcard = wildcard;
             this.installType = installType;
    -        this.password = password;
    +        this.password = Secret.fromString(password);
             this.updateDescription = updateDescription;
             this.qrcodePath = qrcodePath;
             this.envVarsPath = envVarsPath;
         }
     
    -    public String getuKey() {
    +    public Secret getuKey() {
             return uKey;
         }
     
    -    public String getApiKey() {
    +    public Secret getApiKey() {
             return apiKey;
         }
     
    @@ -68,7 +69,7 @@ public String getInstallType() {
             return installType;
         }
     
    -    public String getPassword() {
    +    public Secret getPassword() {
             return password;
         }
     
    @@ -87,12 +88,12 @@ public String getEnvVarsPath() {
         @Override
         public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
             ParamsBeanV1 paramsBeanV1 = new ParamsBeanV1();
    -        paramsBeanV1.setUkey(uKey);
    -        paramsBeanV1.setApiKey(apiKey);
    +        paramsBeanV1.setUkey(uKey.getPlainText());
    +        paramsBeanV1.setApiKey(apiKey.getPlainText());
             paramsBeanV1.setScandir(scanDir);
             paramsBeanV1.setWildcard(wildcard);
             paramsBeanV1.setInstallType(installType);
    -        paramsBeanV1.setPassword(password);
    +        paramsBeanV1.setPassword(password.getPlainText());
             paramsBeanV1.setUpdateDescription(updateDescription);
             paramsBeanV1.setQrcodePath(qrcodePath);
             paramsBeanV1.setEnvVarsPath(envVarsPath);
    @@ -115,17 +116,13 @@ public FormValidation doCheckUKey(@QueryParameter String value)
                     throws IOException, ServletException {
                 if (value.length() == 0)
                     return FormValidation.error("Please set a uKey");
    -            if (!value.matches("[A-Za-z0-9]{32}"))
    -                return FormValidation.warning("Is this correct?");
                 return FormValidation.ok();
             }
     
             public FormValidation doCheckApiKey(@QueryParameter String value)
                     throws IOException, ServletException {
                 if (value.length() == 0)
                     return FormValidation.error("Please set a api_key");
    -            if (!value.matches("[A-Za-z0-9]{32}"))
    -                return FormValidation.warning("Is this correct?");
                 return FormValidation.ok();
             }
     
    
  • src/main/java/ren/helloworld/upload2pgyer/UploadBuilderV2.java+9 10 modified
    @@ -8,6 +8,7 @@
     import hudson.tasks.BuildStepDescriptor;
     import hudson.tasks.Builder;
     import hudson.util.FormValidation;
    +import hudson.util.Secret;
     import org.jenkinsci.Symbol;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.QueryParameter;
    @@ -24,11 +25,11 @@
      */
     public class UploadBuilderV2 extends Builder {
     
    -    private String apiKey;
    +    private Secret apiKey;
         private String scanDir;
         private String wildcard;
         private String buildInstallType;
    -    private String buildPassword;
    +    private Secret buildPassword;
         private String buildUpdateDescription;
         private String buildName;
     
    @@ -37,18 +38,18 @@ public class UploadBuilderV2 extends Builder {
     
         @DataBoundConstructor
         public UploadBuilderV2(String apiKey, String scanDir, String wildcard, String buildName, String buildInstallType, String buildPassword, String buildUpdateDescription, String qrcodePath, String envVarsPath) {
    -        this.apiKey = apiKey;
    +        this.apiKey = Secret.fromString(apiKey);
             this.scanDir = scanDir;
             this.wildcard = wildcard;
             this.buildName = buildName;
    -        this.buildPassword = buildPassword;
    +        this.buildPassword = Secret.fromString(buildPassword);
             this.buildInstallType = buildInstallType;
             this.buildUpdateDescription = buildUpdateDescription;
             this.qrcodePath = qrcodePath;
             this.envVarsPath = envVarsPath;
         }
     
    -    public String getApiKey() {
    +    public Secret getApiKey() {
             return apiKey;
         }
     
    @@ -64,7 +65,7 @@ public String getBuildInstallType() {
             return buildInstallType;
         }
     
    -    public String getBuildPassword() {
    +    public Secret getBuildPassword() {
             return buildPassword;
         }
     
    @@ -87,10 +88,10 @@ public String getEnvVarsPath() {
         @Override
         public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
             ParamsBeanV2 paramsBeanV2 = new ParamsBeanV2();
    -        paramsBeanV2.setApiKey(apiKey);
    +        paramsBeanV2.setApiKey(apiKey.getPlainText());
             paramsBeanV2.setScandir(scanDir);
             paramsBeanV2.setWildcard(wildcard);
    -        paramsBeanV2.setBuildPassword(buildPassword);
    +        paramsBeanV2.setBuildPassword(buildPassword.getPlainText());
             paramsBeanV2.setBuildInstallType(buildInstallType);
             paramsBeanV2.setBuildUpdateDescription(buildUpdateDescription);
             paramsBeanV2.setBuildName(buildName);
    @@ -115,8 +116,6 @@ public FormValidation doCheckApiKey(@QueryParameter String value)
                     throws IOException, ServletException {
                 if (value.length() == 0)
                     return FormValidation.error("Please set a api_key");
    -            if (!value.matches("[A-Za-z0-9]{32}"))
    -                return FormValidation.warning("Is this correct?");
                 return FormValidation.ok();
             }
     
    
  • src/main/java/ren/helloworld/upload2pgyer/UploadPublisher.java+13 16 modified
    @@ -10,6 +10,7 @@
     import hudson.tasks.Publisher;
     import hudson.tasks.Recorder;
     import hudson.util.FormValidation;
    +import hudson.util.Secret;
     import org.jenkinsci.Symbol;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.QueryParameter;
    @@ -26,35 +27,35 @@
      */
     public class UploadPublisher extends Recorder {
     
    -    private String uKey;
    -    private String apiKey;
    +    private Secret uKey;
    +    private Secret apiKey;
         private String scanDir;
         private String wildcard;
         private String installType;
    -    private String password;
    +    private Secret password;
         private String updateDescription;
     
         private String qrcodePath;
         private String envVarsPath;
     
         @DataBoundConstructor
         public UploadPublisher(String uKey, String apiKey, String scanDir, String wildcard, String installType, String password, String updateDescription, String qrcodePath, String envVarsPath) {
    -        this.uKey = uKey;
    -        this.apiKey = apiKey;
    +        this.uKey = Secret.fromString(uKey);
    +        this.apiKey = Secret.fromString(apiKey);
             this.scanDir = scanDir;
             this.wildcard = wildcard;
             this.installType = installType;
    -        this.password = password;
    +        this.password = Secret.fromString(password);
             this.updateDescription = updateDescription;
             this.qrcodePath = qrcodePath;
             this.envVarsPath = envVarsPath;
         }
     
    -    public String getuKey() {
    +    public Secret getuKey() {
             return uKey;
         }
     
    -    public String getApiKey() {
    +    public Secret getApiKey() {
             return apiKey;
         }
     
    @@ -70,7 +71,7 @@ public String getInstallType() {
             return installType;
         }
     
    -    public String getPassword() {
    +    public Secret getPassword() {
             return password;
         }
     
    @@ -89,12 +90,12 @@ public String getEnvVarsPath() {
         @Override
         public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
             ParamsBeanV1 bean = new ParamsBeanV1();
    -        bean.setApiKey(apiKey);
    -        bean.setUkey(uKey);
    +        bean.setApiKey(apiKey.getPlainText());
    +        bean.setUkey(uKey.getPlainText());
             bean.setScandir(scanDir);
             bean.setWildcard(wildcard);
             bean.setInstallType(installType);
    -        bean.setPassword(password);
    +        bean.setPassword(password.getPlainText());
             bean.setUpdateDescription(updateDescription);
             bean.setQrcodePath(qrcodePath);
             bean.setEnvVarsPath(envVarsPath);
    @@ -117,17 +118,13 @@ public FormValidation doCheckUKey(@QueryParameter String value)
                     throws IOException, ServletException {
                 if (value.length() == 0)
                     return FormValidation.error("Please set a uKey");
    -            if (!value.matches("[A-Za-z0-9]{32}"))
    -                return FormValidation.warning("Is this correct?");
                 return FormValidation.ok();
             }
     
             public FormValidation doCheckApiKey(@QueryParameter String value)
                     throws IOException, ServletException {
                 if (value.length() == 0)
                     return FormValidation.error("Please set a api_key");
    -            if (!value.matches("[A-Za-z0-9]{32}"))
    -                return FormValidation.warning("Is this correct?");
                 return FormValidation.ok();
             }
     
    
  • src/main/java/ren/helloworld/upload2pgyer/UploadPublisherV2.java+9 10 modified
    @@ -10,6 +10,7 @@
     import hudson.tasks.Publisher;
     import hudson.tasks.Recorder;
     import hudson.util.FormValidation;
    +import hudson.util.Secret;
     import org.jenkinsci.Symbol;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.QueryParameter;
    @@ -26,11 +27,11 @@
      */
     public class UploadPublisherV2 extends Recorder {
     
    -    private String apiKey;
    +    private Secret apiKey;
         private String scanDir;
         private String wildcard;
         private String buildInstallType;
    -    private String buildPassword;
    +    private Secret buildPassword;
         private String buildUpdateDescription;
         private String buildName;
     
    @@ -39,18 +40,18 @@ public class UploadPublisherV2 extends Recorder {
     
         @DataBoundConstructor
         public UploadPublisherV2(String apiKey, String scanDir, String wildcard, String buildName, String buildInstallType, String buildPassword, String buildUpdateDescription, String qrcodePath, String envVarsPath) {
    -        this.apiKey = apiKey;
    +        this.apiKey = Secret.fromString(apiKey);
             this.scanDir = scanDir;
             this.wildcard = wildcard;
             this.buildName = buildName;
    -        this.buildPassword = buildPassword;
    +        this.buildPassword = Secret.fromString(buildPassword);
             this.buildInstallType = buildInstallType;
             this.buildUpdateDescription = buildUpdateDescription;
             this.qrcodePath = qrcodePath;
             this.envVarsPath = envVarsPath;
         }
     
    -    public String getApiKey() {
    +    public Secret getApiKey() {
             return apiKey;
         }
     
    @@ -66,7 +67,7 @@ public String getBuildInstallType() {
             return buildInstallType;
         }
     
    -    public String getBuildPassword() {
    +    public Secret getBuildPassword() {
             return buildPassword;
         }
     
    @@ -89,10 +90,10 @@ public String getEnvVarsPath() {
         @Override
         public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
             ParamsBeanV2 paramsBeanV2 = new ParamsBeanV2();
    -        paramsBeanV2.setApiKey(apiKey);
    +        paramsBeanV2.setApiKey(apiKey.getPlainText());
             paramsBeanV2.setScandir(scanDir);
             paramsBeanV2.setWildcard(wildcard);
    -        paramsBeanV2.setBuildPassword(buildPassword);
    +        paramsBeanV2.setBuildPassword(buildPassword.getPlainText());
             paramsBeanV2.setBuildInstallType(buildInstallType);
             paramsBeanV2.setBuildName(buildName);
             paramsBeanV2.setBuildUpdateDescription(buildUpdateDescription);
    @@ -117,8 +118,6 @@ public FormValidation doCheckApiKey(@QueryParameter String value)
                     throws IOException, ServletException {
                 if (value.length() == 0)
                     return FormValidation.error("Please set a api_key");
    -            if (!value.matches("[A-Za-z0-9]{32}"))
    -                return FormValidation.warning("Is this correct?");
                 return FormValidation.ok();
             }
     
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadBuilder/config.jelly+1 1 modified
    @@ -25,7 +25,7 @@
             </f:entry>
     
             <f:entry title="password(optional)" field="password">
    -            <f:textbox/>
    +            <f:password/>
             </f:entry>
     
             <f:entry title="updateDescription(optional)" field="updateDescription">
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadBuilder/help-apiKey.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Required) API Key, used to identify the identity of the API caller,<br/>
         if not specified, each interface needs to contain this parameter.<br/>
         For the same pgyer registered users, this value is fixed.<br/>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadBuilder/help-password.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Optional) set the App installation password,<br/>
         if you do not want to set the password, please pass empty string, or not pass.
     </div>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadBuilder/help-uKey.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Required) User Key, used to identify the current user's identity,<br/>
         for the same pgyer registered users, the value of the fixed!<br/>
         <a href="https://www.pgyer.com/account/api" target="_blank" style="color:#FF0000;">Click to get pgyer uKey</a>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadBuilderV2/config.jelly+1 1 modified
    @@ -25,7 +25,7 @@
             </f:entry>
     
             <f:entry title="buildPassword(optional)" field="buildPassword">
    -            <f:textbox/>
    +            <f:password/>
             </f:entry>
     
             <f:entry title="buildUpdateDescription(optional)" field="buildUpdateDescription">
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadBuilderV2/help-apiKey.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Required) API Key, used to identify the identity of the API caller,<br/>
         if not specified, each interface needs to contain this parameter.<br/>
         For the same pgyer registered users, this value is fixed.<br/>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadBuilderV2/help-buildPassword.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Optional) Setting App installation password.<br/>
         If you do not want to set a password, please pass on an empty string or do not pass anything.
     </div>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadPublisher/config.jelly+1 1 modified
    @@ -25,7 +25,7 @@
             </f:entry>
     
             <f:entry title="password(optional)" field="password">
    -            <f:textbox/>
    +            <f:password/>
             </f:entry>
     
             <f:entry title="updateDescription(optional)" field="updateDescription">
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadPublisher/help-apiKey.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Required) API Key, used to identify the identity of the API caller,<br/>
         if not specified, each interface needs to contain this parameter.<br/>
         For the same pgyer registered users, this value is fixed.<br/>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadPublisher/help-password.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Optional) set the App installation password,<br/>
         if you do not want to set the password, please pass empty string, or not pass.
     </div>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadPublisher/help-uKey.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Required) User Key, used to identify the current user's identity,<br/>
         for the same pgyer registered users, the value of the fixed!<br/>
         <a href="https://www.pgyer.com/account/api" target="_blank" style="color:#FF0000;">Click to get pgyer uKey</a>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadPublisherV2/config.jelly+1 1 modified
    @@ -25,7 +25,7 @@
             </f:entry>
     
             <f:entry title="buildPassword(optional)" field="buildPassword">
    -            <f:textbox/>
    +            <f:password/>
             </f:entry>
     
             <f:entry title="buildUpdateDescription(optional)" field="buildUpdateDescription">
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadPublisherV2/help-apiKey.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Required) API Key, used to identify the identity of the API caller,<br/>
         if not specified, each interface needs to contain this parameter.<br/>
         For the same pgyer registered users, this value is fixed.<br/>
    
  • src/main/resources/ren/helloworld/upload2pgyer/UploadPublisherV2/help-buildPassword.html+1 0 modified
    @@ -1,4 +1,5 @@
     <div>
    +    <b>To be safe, the field needs to be encrypted, so it looks that long.</b><br/>
         (Optional) Setting App installation password.<br/>
         If you do not want to set a password, please pass on an empty string or do not pass anything.
     </div>
    

Vulnerability mechanics

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

References

6

News mentions

0

No linked articles in our index yet.