VYPR
Moderate severityNVD Advisory· Published Jul 2, 2020· Updated Aug 4, 2024

CVE-2020-2204

CVE-2020-2204

Description

Missing permission check in Jenkins Fortify on Demand Plugin allows attackers with Overall/Read to connect to the globally configured endpoint using attacker-specified credentials IDs.

AI Insight

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

Missing permission check in Jenkins Fortify on Demand Plugin allows attackers with Overall/Read to connect to the globally configured endpoint using attacker-specified credentials IDs.

Vulnerability

Overview

The Jenkins Fortify on Demand Plugin versions 5.0.1 and earlier contains a missing permission check vulnerability [CVE-2020-2204]. The plugin failed to properly enforce authorization on methods that populate credential ID selection lists, such as doFillClientIdItems() and doFillClientSecretItems(). These methods originally called SharedUploadBuildStep.doFillStringCredentialsItems() without verifying that the caller had the ADMINISTER permission [1].

Exploitation

An attacker with only Overall/Read permission could exploit this by directly invoking these form-fill methods. The plugin would then connect to the globally configured Fortify on Demand endpoint using credentials IDs supplied by the attacker, rather than the administrator-configured credentials. The attacker does not need to know the credentials themselves—only the credential IDs, which could be enumerated via another issue [SECURITY-1690, CVE-2020-2202] in the same advisory [3]. This attack can be performed without authentication to the Fortify on Demand service.

Impact

A successful exploit allows an attacker to make the Jenkins instance connect to the Fortify on Demand endpoint using arbitrary credential IDs from the Jenkins credential store, potentially leading to credential misuse or denial of service. The ability to specify credential IDs could also be combined with other vulnerabilities to capture credentials or perform actions under the guise of the configured service account.

Mitigation

The vulnerability is patched in Fortify on Demand Plugin 6.0.1 [3][4]. The fix adds a permission check (Jenkins.get().checkPermission(Jenkins.ADMINISTER)) before accessing credential ID lists [1][2]. Users are advised to update to version 6.0.1 or later as soon as possible.

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.

PackageAffected versionsPatched versions
org.jenkins-ci.plugins:fortify-on-demand-uploaderMaven
< 6.0.16.0.1

Affected products

2

Patches

2
006c2336d578

Merge pull request #105 from fod-dev/master

7 files changed · +100 47
  • src/main/java/org/jenkinsci/plugins/fodupload/FodGlobalDescriptor.java+27 5 modified
    @@ -1,6 +1,11 @@
     package org.jenkinsci.plugins.fodupload;
    
     
    
    +import com.cloudbees.plugins.credentials.CredentialsProvider;
    
     import hudson.Extension;
    
    +import hudson.model.Item;
    
    +import hudson.model.Job;
    
    +import hudson.security.ACL;
    
    +import hudson.security.Permission;
    
     import hudson.util.FormValidation;
    
     import hudson.util.ListBoxModel;
    
     import hudson.util.Secret;
    
    @@ -13,6 +18,7 @@
     
    
     import jenkins.model.Jenkins;
    
     import org.jenkinsci.plugins.fodupload.models.FodEnums.GrantType;
    
    +import org.jenkinsci.plugins.plaincredentials.StringCredentials;
    
     import org.kohsuke.stapler.verb.POST;
    
     
    
     @Extension
    
    @@ -189,27 +195,32 @@ public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(USERNA
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillClientIdItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillClientSecretItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillUsernameItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillPersonalAccessTokenItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillTenantIdItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         FodApiConnection createFodApiConnection() {
    
    @@ -262,6 +273,17 @@ public FormValidation testConnection(FodApiConnection testApi) {
                     FormValidation.ok("Successfully authenticated to Fortify on Demand.") :
    
                     FormValidation.error("Invalid connection information. Please check your credentials and try again.");
    
         }
    
    +
    
    +    private ListBoxModel doFillStringCredentialsItems(){
    
    +        ListBoxModel items = CredentialsProvider.listCredentials(
    
    +                StringCredentials.class,
    
    +                Jenkins.get(),
    
    +                ACL.SYSTEM,
    
    +                null,
    
    +                null
    
    +                );
    
    +        return items;
    
    +    }
    
         
    
         
    
     }
    
    
  • src/main/java/org/jenkinsci/plugins/fodupload/PollingBuildStep.java+13 9 modified
    @@ -7,6 +7,8 @@
     import hudson.FilePath;
    
     import hudson.Launcher;
    
     import hudson.model.AbstractProject;
    
    +import hudson.model.Item;
    
    +import hudson.model.Job;
    
     import hudson.model.Result;
    
     import hudson.model.Run;
    
     import hudson.model.TaskListener;
    
    @@ -35,6 +37,7 @@
     import org.kohsuke.stapler.verb.POST;
    
     
    
     import static org.jenkinsci.plugins.fodupload.SharedPollingBuildStep.*;
    
    +import org.kohsuke.stapler.AncestorInPath;
    
     
    
     @SuppressWarnings("unused")
    
     public class PollingBuildStep extends Recorder implements SimpleBuildStep {
    
    @@ -160,9 +163,10 @@ public FormValidation doCheckPollingInterval(@QueryParameter String pollingInter
             @POST
    
             public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(USERNAME) final String username,
    
                                                                       @QueryParameter(PERSONAL_ACCESS_TOKEN) final String personalAccessToken,
    
    -                                                                  @QueryParameter(TENANT_ID) final String tenantId) {
    
    -            Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    -            return SharedPollingBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId);
    
    +                                                                  @QueryParameter(TENANT_ID) final String tenantId,
    
    +                                                                  @AncestorInPath Job job) {
    
    +            job.checkPermission(Item.CONFIGURE);
    
    +            return SharedPollingBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId, job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    @@ -171,18 +175,18 @@ public ListBoxModel doFillPolicyFailureBuildResultPreferenceItems() {
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillUsernameItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillUsernameItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillPersonalAccessTokenItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillPersonalAccessTokenItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillTenantIdItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillTenantIdItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
         }
    
     }
    
    
  • src/main/java/org/jenkinsci/plugins/fodupload/SharedPollingBuildStep.java+10 3 modified
    @@ -17,6 +17,8 @@
     import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
    
     import hudson.FilePath;
    
     import hudson.Launcher;
    
    +import hudson.model.Item;
    
    +import hudson.model.Job;
    
     import hudson.model.Result;
    
     import hudson.model.Run;
    
     import hudson.model.TaskListener;
    
    @@ -25,6 +27,8 @@
     import hudson.util.ListBoxModel;
    
     import jenkins.model.GlobalConfiguration;
    
     import jenkins.model.Jenkins;
    
    +import org.kohsuke.stapler.AncestorInPath;
    
    +
    
     import org.kohsuke.stapler.verb.POST;
    
     
    
     public class SharedPollingBuildStep {
    
    @@ -123,8 +127,10 @@ public static FormValidation doCheckPollingInterval(String pollingInterval) {
         @POST
    
         public static FormValidation doTestPersonalAccessTokenConnection(final String username,
    
                                                                          final String personalAccessToken,
    
    -                                                                     final String tenantId) {
    
    -        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +                                                                     final String tenantId,
    
    +                                                                     @AncestorInPath Job job) {
    
    +        job.checkPermission(Item.CONFIGURE);
    
    +
    
             FodApiConnection testApi;
    
             String baseUrl = GlobalConfiguration.all().get(FodGlobalDescriptor.class).getBaseUrl();
    
             String apiUrl = GlobalConfiguration.all().get(FodGlobalDescriptor.class).getApiUrl();
    
    @@ -154,7 +160,8 @@ public static ListBoxModel doFillPolicyFailureBuildResultPreferenceItems() {
         }
    
     
    
         @SuppressWarnings("unused")
    
    -    public static ListBoxModel doFillStringCredentialsItems() {
    
    +    public static ListBoxModel doFillStringCredentialsItems(@AncestorInPath Job job) {
    
    +        job.checkPermission(Item.CONFIGURE);
    
             ListBoxModel items = CredentialsProvider.listCredentials(
    
                     StringCredentials.class,
    
                     Jenkins.get(),
    
    
  • src/main/java/org/jenkinsci/plugins/fodupload/SharedUploadBuildStep.java+8 3 modified
    @@ -21,6 +21,8 @@
     import hudson.Launcher;
     import hudson.model.AbstractBuild;
     import hudson.model.BuildListener;
    +import hudson.model.Item;
    +import hudson.model.Job;
     import hudson.model.Result;
     import hudson.model.Run;
     import hudson.model.TaskListener;
    @@ -29,6 +31,7 @@
     import hudson.util.ListBoxModel;
     import jenkins.model.GlobalConfiguration;
     import jenkins.model.Jenkins;
    +import org.kohsuke.stapler.AncestorInPath;
     import org.kohsuke.stapler.verb.POST;
     
     public class SharedUploadBuildStep {
    @@ -113,8 +116,9 @@ public static FormValidation doCheckBsiToken(String bsiToken, String releaseId)
         @POST
         public static FormValidation doTestPersonalAccessTokenConnection(final String username,
                                                                          final String personalAccessToken,
    -                                                                     final String tenantId) {
    -        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    +                                                                     final String tenantId,
    +                                                                     @AncestorInPath Job job) {
    +        job.checkPermission(Item.CONFIGURE);
             FodApiConnection testApi;
             String baseUrl = GlobalConfiguration.all().get(FodGlobalDescriptor.class).getBaseUrl();
             String apiUrl = GlobalConfiguration.all().get(FodGlobalDescriptor.class).getApiUrl();
    @@ -154,7 +158,8 @@ public static ListBoxModel doFillRemediationScanPreferenceTypeItems() {
         }
     
         @SuppressWarnings("unused")
    -    public static ListBoxModel doFillStringCredentialsItems() {
    +    public static ListBoxModel doFillStringCredentialsItems(@AncestorInPath Job job) {
    +        job.checkPermission(Item.CONFIGURE);
             ListBoxModel items = CredentialsProvider.listCredentials(
                     StringCredentials.class,
                     Jenkins.get(),
    
  • src/main/java/org/jenkinsci/plugins/fodupload/StaticAssessmentBuildStep.java+13 9 modified
    @@ -7,6 +7,8 @@
     import hudson.model.AbstractBuild;
     import hudson.model.AbstractProject;
     import hudson.model.BuildListener;
    +import hudson.model.Item;
    +import hudson.model.Job;
     import hudson.model.Run;
     import hudson.model.TaskListener;
     import hudson.security.Permission;
    @@ -31,6 +33,7 @@
     
     import jenkins.model.Jenkins;
     import org.jenkinsci.plugins.fodupload.models.AuthenticationModel;
    +import org.kohsuke.stapler.AncestorInPath;
     import org.kohsuke.stapler.QueryParameter;
     import org.kohsuke.stapler.verb.POST;
     
    @@ -196,9 +199,10 @@ public String getDisplayName() {
             @POST
             public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(SharedUploadBuildStep.USERNAME) final String username,
                                                                       @QueryParameter(SharedUploadBuildStep.PERSONAL_ACCESS_TOKEN) final String personalAccessToken,
    -                                                                  @QueryParameter(SharedUploadBuildStep.TENANT_ID) final String tenantId) {
    -            Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    -            return SharedUploadBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId);
    +                                                                  @QueryParameter(SharedUploadBuildStep.TENANT_ID) final String tenantId,
    +                                                                  @AncestorInPath Job job) {
    +            job.checkPermission(Item.CONFIGURE);
    +            return SharedUploadBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId,job);
             }
     
             @SuppressWarnings("unused")
    @@ -213,18 +217,18 @@ public ListBoxModel doFillRemediationScanPreferenceTypeItems() {
     
             @SuppressWarnings("unused")
     
    -        public ListBoxModel doFillUsernameItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillUsernameItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillPersonalAccessTokenItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillPersonalAccessTokenItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillTenantIdItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillTenantIdItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    
  • src/main/java/org/jenkinsci/plugins/fodupload/steps/FortifyPollResults.java+15 9 modified
    @@ -22,11 +22,15 @@
     import hudson.Launcher;
    
     import hudson.model.AbstractBuild;
    
     import hudson.model.BuildListener;
    
    +import hudson.model.Item;
    
    +import hudson.model.Job;
    
     import hudson.model.Run;
    
     import hudson.model.TaskListener;
    
     import hudson.util.FormValidation;
    
     import hudson.util.ListBoxModel;
    
     import hudson.util.Secret;
    
    +import org.kohsuke.stapler.AncestorInPath;
    
    +
    
     import org.kohsuke.stapler.verb.POST;
    
     
    
     @SuppressFBWarnings("unused")
    
    @@ -193,9 +197,11 @@ public Set<? extends Class<?>> getRequiredContext() {
             @POST
    
             public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(SharedPollingBuildStep.USERNAME) final String username,
    
                                                                       @QueryParameter(SharedPollingBuildStep.PERSONAL_ACCESS_TOKEN) final String personalAccessToken,
    
    -                                                                  @QueryParameter(SharedPollingBuildStep.TENANT_ID) final String tenantId) {
    
    -            Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    -            return SharedPollingBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId);
    
    +                                                                  @QueryParameter(SharedPollingBuildStep.TENANT_ID) final String tenantId,
    
    +                                                                  @AncestorInPath Job job) {
    
    +            job.checkPermission(Item.CONFIGURE);
    
    +            return SharedPollingBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId, job);
    
    +
    
     
    
             }
    
     
    
    @@ -205,18 +211,18 @@ public ListBoxModel doFillPolicyFailureBuildResultPreferenceItems() {
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillUsernameItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillUsernameItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillPersonalAccessTokenItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillPersonalAccessTokenItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillTenantIdItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillTenantIdItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
         }
    
    
  • src/main/java/org/jenkinsci/plugins/fodupload/steps/FortifyStaticAssessment.java+14 9 modified
    @@ -21,11 +21,14 @@
     import hudson.Launcher;
     import hudson.model.AbstractBuild;
     import hudson.model.BuildListener;
    +import hudson.model.Item;
    +import hudson.model.Job;
     import hudson.model.Run;
     import hudson.model.TaskListener;
     import hudson.util.FormValidation;
     import hudson.util.ListBoxModel;
     import hudson.util.Secret;
    +import org.kohsuke.stapler.AncestorInPath;
     import org.kohsuke.stapler.verb.POST;
     
     
    @@ -211,9 +214,11 @@ public Set<? extends Class<?>> getRequiredContext() {
             @POST
             public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(SharedUploadBuildStep.USERNAME) final String username,
                                                                       @QueryParameter(SharedUploadBuildStep.PERSONAL_ACCESS_TOKEN) final String personalAccessToken,
    -                                                                  @QueryParameter(SharedUploadBuildStep.TENANT_ID) final String tenantId) {
    -            Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    -            return SharedUploadBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId);
    +                                                                  @QueryParameter(SharedUploadBuildStep.TENANT_ID) final String tenantId,
    +                                                                  @AncestorInPath Job job) {
    +            job.checkPermission(Item.CONFIGURE);
    +            return SharedUploadBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId, job);
    +
     
             }
     
    @@ -228,18 +233,18 @@ public ListBoxModel doFillRemediationScanPreferenceTypeItems() {
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillUsernameItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillUsernameItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillPersonalAccessTokenItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillPersonalAccessTokenItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillTenantIdItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillTenantIdItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    
28932f7c5ff1

SECURITY-1690 and SECURITY-1691 fixes

7 files changed · +100 47
  • src/main/java/org/jenkinsci/plugins/fodupload/FodGlobalDescriptor.java+27 5 modified
    @@ -1,6 +1,11 @@
     package org.jenkinsci.plugins.fodupload;
    
     
    
    +import com.cloudbees.plugins.credentials.CredentialsProvider;
    
     import hudson.Extension;
    
    +import hudson.model.Item;
    
    +import hudson.model.Job;
    
    +import hudson.security.ACL;
    
    +import hudson.security.Permission;
    
     import hudson.util.FormValidation;
    
     import hudson.util.ListBoxModel;
    
     import hudson.util.Secret;
    
    @@ -13,6 +18,7 @@
     
    
     import jenkins.model.Jenkins;
    
     import org.jenkinsci.plugins.fodupload.models.FodEnums.GrantType;
    
    +import org.jenkinsci.plugins.plaincredentials.StringCredentials;
    
     import org.kohsuke.stapler.verb.POST;
    
     
    
     @Extension
    
    @@ -189,27 +195,32 @@ public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(USERNA
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillClientIdItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillClientSecretItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillUsernameItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillPersonalAccessTokenItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         @SuppressWarnings("unused")
    
         public ListBoxModel doFillTenantIdItems() {
    
    -        return SharedUploadBuildStep.doFillStringCredentialsItems();
    
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +        return doFillStringCredentialsItems();
    
         }
    
     
    
         FodApiConnection createFodApiConnection() {
    
    @@ -262,6 +273,17 @@ public FormValidation testConnection(FodApiConnection testApi) {
                     FormValidation.ok("Successfully authenticated to Fortify on Demand.") :
    
                     FormValidation.error("Invalid connection information. Please check your credentials and try again.");
    
         }
    
    +
    
    +    private ListBoxModel doFillStringCredentialsItems(){
    
    +        ListBoxModel items = CredentialsProvider.listCredentials(
    
    +                StringCredentials.class,
    
    +                Jenkins.get(),
    
    +                ACL.SYSTEM,
    
    +                null,
    
    +                null
    
    +                );
    
    +        return items;
    
    +    }
    
         
    
         
    
     }
    
    
  • src/main/java/org/jenkinsci/plugins/fodupload/PollingBuildStep.java+13 9 modified
    @@ -7,6 +7,8 @@
     import hudson.FilePath;
    
     import hudson.Launcher;
    
     import hudson.model.AbstractProject;
    
    +import hudson.model.Item;
    
    +import hudson.model.Job;
    
     import hudson.model.Result;
    
     import hudson.model.Run;
    
     import hudson.model.TaskListener;
    
    @@ -35,6 +37,7 @@
     import org.kohsuke.stapler.verb.POST;
    
     
    
     import static org.jenkinsci.plugins.fodupload.SharedPollingBuildStep.*;
    
    +import org.kohsuke.stapler.AncestorInPath;
    
     
    
     @SuppressWarnings("unused")
    
     public class PollingBuildStep extends Recorder implements SimpleBuildStep {
    
    @@ -160,9 +163,10 @@ public FormValidation doCheckPollingInterval(@QueryParameter String pollingInter
             @POST
    
             public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(USERNAME) final String username,
    
                                                                       @QueryParameter(PERSONAL_ACCESS_TOKEN) final String personalAccessToken,
    
    -                                                                  @QueryParameter(TENANT_ID) final String tenantId) {
    
    -            Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    -            return SharedPollingBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId);
    
    +                                                                  @QueryParameter(TENANT_ID) final String tenantId,
    
    +                                                                  @AncestorInPath Job job) {
    
    +            job.checkPermission(Item.CONFIGURE);
    
    +            return SharedPollingBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId, job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    @@ -171,18 +175,18 @@ public ListBoxModel doFillPolicyFailureBuildResultPreferenceItems() {
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillUsernameItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillUsernameItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillPersonalAccessTokenItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillPersonalAccessTokenItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillTenantIdItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillTenantIdItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
         }
    
     }
    
    
  • src/main/java/org/jenkinsci/plugins/fodupload/SharedPollingBuildStep.java+10 3 modified
    @@ -17,6 +17,8 @@
     import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
    
     import hudson.FilePath;
    
     import hudson.Launcher;
    
    +import hudson.model.Item;
    
    +import hudson.model.Job;
    
     import hudson.model.Result;
    
     import hudson.model.Run;
    
     import hudson.model.TaskListener;
    
    @@ -25,6 +27,8 @@
     import hudson.util.ListBoxModel;
    
     import jenkins.model.GlobalConfiguration;
    
     import jenkins.model.Jenkins;
    
    +import org.kohsuke.stapler.AncestorInPath;
    
    +
    
     import org.kohsuke.stapler.verb.POST;
    
     
    
     public class SharedPollingBuildStep {
    
    @@ -123,8 +127,10 @@ public static FormValidation doCheckPollingInterval(String pollingInterval) {
         @POST
    
         public static FormValidation doTestPersonalAccessTokenConnection(final String username,
    
                                                                          final String personalAccessToken,
    
    -                                                                     final String tenantId) {
    
    -        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    +                                                                     final String tenantId,
    
    +                                                                     @AncestorInPath Job job) {
    
    +        job.checkPermission(Item.CONFIGURE);
    
    +
    
             FodApiConnection testApi;
    
             String baseUrl = GlobalConfiguration.all().get(FodGlobalDescriptor.class).getBaseUrl();
    
             String apiUrl = GlobalConfiguration.all().get(FodGlobalDescriptor.class).getApiUrl();
    
    @@ -154,7 +160,8 @@ public static ListBoxModel doFillPolicyFailureBuildResultPreferenceItems() {
         }
    
     
    
         @SuppressWarnings("unused")
    
    -    public static ListBoxModel doFillStringCredentialsItems() {
    
    +    public static ListBoxModel doFillStringCredentialsItems(@AncestorInPath Job job) {
    
    +        job.checkPermission(Item.CONFIGURE);
    
             ListBoxModel items = CredentialsProvider.listCredentials(
    
                     StringCredentials.class,
    
                     Jenkins.get(),
    
    
  • src/main/java/org/jenkinsci/plugins/fodupload/SharedUploadBuildStep.java+8 3 modified
    @@ -21,6 +21,8 @@
     import hudson.Launcher;
     import hudson.model.AbstractBuild;
     import hudson.model.BuildListener;
    +import hudson.model.Item;
    +import hudson.model.Job;
     import hudson.model.Result;
     import hudson.model.Run;
     import hudson.model.TaskListener;
    @@ -29,6 +31,7 @@
     import hudson.util.ListBoxModel;
     import jenkins.model.GlobalConfiguration;
     import jenkins.model.Jenkins;
    +import org.kohsuke.stapler.AncestorInPath;
     import org.kohsuke.stapler.verb.POST;
     
     public class SharedUploadBuildStep {
    @@ -113,8 +116,9 @@ public static FormValidation doCheckBsiToken(String bsiToken, String releaseId)
         @POST
         public static FormValidation doTestPersonalAccessTokenConnection(final String username,
                                                                          final String personalAccessToken,
    -                                                                     final String tenantId) {
    -        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    +                                                                     final String tenantId,
    +                                                                     @AncestorInPath Job job) {
    +        job.checkPermission(Item.CONFIGURE);
             FodApiConnection testApi;
             String baseUrl = GlobalConfiguration.all().get(FodGlobalDescriptor.class).getBaseUrl();
             String apiUrl = GlobalConfiguration.all().get(FodGlobalDescriptor.class).getApiUrl();
    @@ -154,7 +158,8 @@ public static ListBoxModel doFillRemediationScanPreferenceTypeItems() {
         }
     
         @SuppressWarnings("unused")
    -    public static ListBoxModel doFillStringCredentialsItems() {
    +    public static ListBoxModel doFillStringCredentialsItems(@AncestorInPath Job job) {
    +        job.checkPermission(Item.CONFIGURE);
             ListBoxModel items = CredentialsProvider.listCredentials(
                     StringCredentials.class,
                     Jenkins.get(),
    
  • src/main/java/org/jenkinsci/plugins/fodupload/StaticAssessmentBuildStep.java+13 9 modified
    @@ -7,6 +7,8 @@
     import hudson.model.AbstractBuild;
     import hudson.model.AbstractProject;
     import hudson.model.BuildListener;
    +import hudson.model.Item;
    +import hudson.model.Job;
     import hudson.model.Run;
     import hudson.model.TaskListener;
     import hudson.security.Permission;
    @@ -31,6 +33,7 @@
     
     import jenkins.model.Jenkins;
     import org.jenkinsci.plugins.fodupload.models.AuthenticationModel;
    +import org.kohsuke.stapler.AncestorInPath;
     import org.kohsuke.stapler.QueryParameter;
     import org.kohsuke.stapler.verb.POST;
     
    @@ -196,9 +199,10 @@ public String getDisplayName() {
             @POST
             public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(SharedUploadBuildStep.USERNAME) final String username,
                                                                       @QueryParameter(SharedUploadBuildStep.PERSONAL_ACCESS_TOKEN) final String personalAccessToken,
    -                                                                  @QueryParameter(SharedUploadBuildStep.TENANT_ID) final String tenantId) {
    -            Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    -            return SharedUploadBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId);
    +                                                                  @QueryParameter(SharedUploadBuildStep.TENANT_ID) final String tenantId,
    +                                                                  @AncestorInPath Job job) {
    +            job.checkPermission(Item.CONFIGURE);
    +            return SharedUploadBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId,job);
             }
     
             @SuppressWarnings("unused")
    @@ -213,18 +217,18 @@ public ListBoxModel doFillRemediationScanPreferenceTypeItems() {
     
             @SuppressWarnings("unused")
     
    -        public ListBoxModel doFillUsernameItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillUsernameItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillPersonalAccessTokenItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillPersonalAccessTokenItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillTenantIdItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillTenantIdItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    
  • src/main/java/org/jenkinsci/plugins/fodupload/steps/FortifyPollResults.java+15 9 modified
    @@ -22,11 +22,15 @@
     import hudson.Launcher;
    
     import hudson.model.AbstractBuild;
    
     import hudson.model.BuildListener;
    
    +import hudson.model.Item;
    
    +import hudson.model.Job;
    
     import hudson.model.Run;
    
     import hudson.model.TaskListener;
    
     import hudson.util.FormValidation;
    
     import hudson.util.ListBoxModel;
    
     import hudson.util.Secret;
    
    +import org.kohsuke.stapler.AncestorInPath;
    
    +
    
     import org.kohsuke.stapler.verb.POST;
    
     
    
     @SuppressFBWarnings("unused")
    
    @@ -193,9 +197,11 @@ public Set<? extends Class<?>> getRequiredContext() {
             @POST
    
             public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(SharedPollingBuildStep.USERNAME) final String username,
    
                                                                       @QueryParameter(SharedPollingBuildStep.PERSONAL_ACCESS_TOKEN) final String personalAccessToken,
    
    -                                                                  @QueryParameter(SharedPollingBuildStep.TENANT_ID) final String tenantId) {
    
    -            Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    
    -            return SharedPollingBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId);
    
    +                                                                  @QueryParameter(SharedPollingBuildStep.TENANT_ID) final String tenantId,
    
    +                                                                  @AncestorInPath Job job) {
    
    +            job.checkPermission(Item.CONFIGURE);
    
    +            return SharedPollingBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId, job);
    
    +
    
     
    
             }
    
     
    
    @@ -205,18 +211,18 @@ public ListBoxModel doFillPolicyFailureBuildResultPreferenceItems() {
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillUsernameItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillUsernameItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillPersonalAccessTokenItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillPersonalAccessTokenItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
             @SuppressWarnings("unused")
    
    -        public ListBoxModel doFillTenantIdItems() {
    
    -            return SharedPollingBuildStep.doFillStringCredentialsItems();
    
    +        public ListBoxModel doFillTenantIdItems(@AncestorInPath Job job) {
    
    +            return SharedPollingBuildStep.doFillStringCredentialsItems(job);
    
             }
    
     
    
         }
    
    
  • src/main/java/org/jenkinsci/plugins/fodupload/steps/FortifyStaticAssessment.java+14 9 modified
    @@ -21,11 +21,14 @@
     import hudson.Launcher;
     import hudson.model.AbstractBuild;
     import hudson.model.BuildListener;
    +import hudson.model.Item;
    +import hudson.model.Job;
     import hudson.model.Run;
     import hudson.model.TaskListener;
     import hudson.util.FormValidation;
     import hudson.util.ListBoxModel;
     import hudson.util.Secret;
    +import org.kohsuke.stapler.AncestorInPath;
     import org.kohsuke.stapler.verb.POST;
     
     
    @@ -211,9 +214,11 @@ public Set<? extends Class<?>> getRequiredContext() {
             @POST
             public FormValidation doTestPersonalAccessTokenConnection(@QueryParameter(SharedUploadBuildStep.USERNAME) final String username,
                                                                       @QueryParameter(SharedUploadBuildStep.PERSONAL_ACCESS_TOKEN) final String personalAccessToken,
    -                                                                  @QueryParameter(SharedUploadBuildStep.TENANT_ID) final String tenantId) {
    -            Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    -            return SharedUploadBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId);
    +                                                                  @QueryParameter(SharedUploadBuildStep.TENANT_ID) final String tenantId,
    +                                                                  @AncestorInPath Job job) {
    +            job.checkPermission(Item.CONFIGURE);
    +            return SharedUploadBuildStep.doTestPersonalAccessTokenConnection(username, personalAccessToken, tenantId, job);
    +
     
             }
     
    @@ -228,18 +233,18 @@ public ListBoxModel doFillRemediationScanPreferenceTypeItems() {
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillUsernameItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillUsernameItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillPersonalAccessTokenItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillPersonalAccessTokenItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    -        public ListBoxModel doFillTenantIdItems() {
    -            return SharedUploadBuildStep.doFillStringCredentialsItems();
    +        public ListBoxModel doFillTenantIdItems(@AncestorInPath Job job) {
    +            return SharedUploadBuildStep.doFillStringCredentialsItems(job);
             }
     
             @SuppressWarnings("unused")
    

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

1