jenkinsci/fortify-on-demand-uploader-plugin

Null pointer exception when running in Jenkins declarative pipeline - plugin version 4.0.1

Opened this issue · 5 comments

I have recently updated from plugin version 4.0.0 to 4.0.1, and I am now getting a null pointer exception in my Jenkins declarative pipeline using the new version of the plugin.

Here is the exception:

java.lang.NullPointerException
	at org.jenkinsci.plugins.fodupload.steps.FortifyStaticAssessment.perform(FortifyStaticAssessment.java:171)
	at org.jenkinsci.plugins.fodupload.steps.FortifyStaticAssessment$Execution.run(FortifyStaticAssessment.java:233)
	at org.jenkinsci.plugins.fodupload.steps.FortifyStaticAssessment$Execution.run(FortifyStaticAssessment.java:221)
	at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834) 

It seems to indicate that there is no username in line 171 of this file: https://github.com/jenkinsci/fortify-on-demand-uploader-plugin/blob/master/src/main/java/org/jenkinsci/plugins/fodupload/steps/FortifyStaticAssessment.java

However, I am passing a username (and personal access token) pulled from the Jenkins credential store:

withCredentials([usernamePassword(credentialsId: "${uploadOptions.fortifyPatCredentials}", passwordVariable: 'FORTIFY_CRED_PSW', usernameVariable: 'FORTIFY_CRED_USR')]) {
   fodStaticAssessment bsiToken: "${bsiToken}", entitlementPreference: 'SubscriptionOnly', inProgressScanActionType: 'DoNotStartScan', overrideGlobalConfig: true, 
      personalAccessToken: "${FORTIFY_CRED_PSW}", remediationScanPreferenceType: 'RemediationScanIfAvailable', srcLocation: "${WORKSPACE}", tenantId: "${globalVars.FORTIFY_TENANT}", username: "${FORTIFY_CRED_USR}"
}

This code worked in 4.0.0, but now gives the NPE in 4.0.1.

It looks to me like the FortifyStaticAssessment step is not encrypting the string and then trying to decrypt the string (which has not been encrypted), which returns a null value. Then the null pointer comes from null.getPlainText()

Can you confirm whether v5.0.0 resolves this issue?

@ewh0005 I had the same exact issue you had with FoD in my Jenkins pipeline. I have a solution if you're still having the problem, however, I'm not sure if you need me to type it all out if you've already solved it yourself.

I am having the same issue in 5.0.0
If I do not pass the a PAT Token (because I am using API authentication)

def fortifyBsiToken = 'XXXXXXXXXXXXXXX'
fodStaticAssessment([ 
            bsiToken: fortifyBsiToken, 
            entitlementPreference: 'SubscriptionOnly', 
            inProgressScanActionType: 'DoNotStartScan',
            overrideGlobalConfig: true, 
            remediationScanPreferenceType: 'NonRemediationScanOnly', 
            srcLocation: 'fortify'
          ])

I get the Null Pointer

[Pipeline] fodStaticAssessment
Running fodStaticAssessment step
Fortify on Demand Upload Running...
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
java.lang.NullPointerException
	at com.cloudbees.plugins.credentials.matchers.IdMatcher.<init>(IdMatcher.java:56)
	at com.cloudbees.plugins.credentials.CredentialsMatchers.withId(CredentialsMatchers.java:132)
	at org.jenkinsci.plugins.fodupload.Utils.isCredential(Utils.java:156)
	at org.jenkinsci.plugins.fodupload.SharedUploadBuildStep.perform(SharedUploadBuildStep.java:182)
	at org.jenkinsci.plugins.fodupload.steps.FortifyStaticAssessment.perform(FortifyStaticAssessment.java:180)
	at org.jenkinsci.plugins.fodupload.steps.FortifyStaticAssessment$Execution.run(FortifyStaticAssessment.java:253)
	at org.jenkinsci.plugins.fodupload.steps.FortifyStaticAssessment$Execution.run(FortifyStaticAssessment.java:241)
	at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Finished: FAILURE

When I place the secret in the pipeline

def fortifyBsiToken = 'XXXXXXXXXXXXXXX'
fodStaticAssessment([ 
            bsiToken: fortifyBsiToken, 
            personalAccessToken: 'fortify_api_secret', // the credential name of the api secret
            entitlementPreference: 'SubscriptionOnly', 
            inProgressScanActionType: 'DoNotStartScan',
            overrideGlobalConfig: true, 
            remediationScanPreferenceType: 'NonRemediationScanOnly', 
            srcLocation: 'fortify'
          ])

I get an unauthorized error.

Do I need both an api key and a pat token? The documentation says that the PAT token is optional.

@jnorthcott

The script you posted has the paramter overrideGlobalConfig: true. If this is removed and the global authentication creds have been set (make sure to provide it again after updating to latest version of the plugin), the global authentication creds should be used.

The following code works in my pipeline script:
fodStaticAssessment bsiToken: '', entitlementPreference: 'SubscriptionFirstThenSingleScan', inProgressScanActionType: 'DoNotStartScan', personalAccessToken: '', remediationScanPreferenceType: 'RemediationScanIfAvailable', srcLocation: '', tenantId: '', username: ''