Hello,
I would like to understand how my code need to look like, so that I don’t see the warning:
The following steps that have been detected may have insecure interpolation of sensitive variables (click here for an explanation):
httpRequest: [BACKUP_PASSWORD]
The API of an non public application requests, that I authenticate against the API with Username and Password, stored in BACKUP_CREDENTIALS and provide an password (Secret BACKUP_PASSWORD) in JSON format in the request body.
When restoring the backup zip file, both credentials need to be provided again.
The warning is indicating that there may be sensitive data being interpolated in the requestBody field of the httpRequest step. In your case, the BACKUP_PASSWORD variable is being used directly in the JSON request body, which could be insecure if the value of BACKUP_PASSWORD is sensitive.
To avoid this warning and make your code more secure, you can use the withCredentials step to securely pass the BACKUP_PASSWORD value to the httpRequest step. Here’s an example of how to modify your code:
In this modified code, the BACKUP_PASSWORD value is passed to the httpRequest step using the withCredentials step, which securely handles the sensitive value. The JSON request body is constructed using a map and JsonOutput.toJson method, rather than directly interpolating the BACKUP_PASSWORD variable. This approach should prevent the warning message from being displayed.
I’m trying to model this with Blue Ocean. timeout is named “Enforce time limit”. httpRequest is named “Perform an HTTP Request and return a response object”
How to model script and withCredentials?
Do I need to use “Evaluate a Groovy source file into the Pipeline script” or “Run arbitrary Pipeline script”?
I found out the answer by copy the code including imports from one to another Jenkinsfile. script is named “Run arbitrary Pipeline script”.
The copy the code from withCredentials into the field.
When using Blue Ocean, you can use the “Run arbitrary Pipeline script” step to run arbitrary Groovy code within your pipeline. This allows you to use any Groovy code, including the withCredentials block, within your pipeline.
You can also use the “Evaluate a Groovy source file into the Pipeline script” step to load Groovy code from an external file into your pipeline. This can be useful if you have a large amount of shared or reusable code that you want to keep in a separate file.
Both of these steps can be used to include the withCredentials block in your pipeline. Just make sure to import the necessary libraries and use the correct syntax when using these steps.
Yes, using variables in the environment and parameters is definitely part of the solution to run your code on multiple target hostnames. Here’s an example of how you couldstore the hostnames in a separate file and read and process the file in your Jenkinsfile:
Create a file named hostnames.txt in your GitHub or workspace location with the list of hostnames, one per line:
hostname1
hostname2
hostname3
...
Add a parameters block to your pipeline to allow the user to input the location of the hostnames.txt file:
pipeline {
parameters {
string(name: 'HOSTNAMES_FILE', defaultValue: 'hostnames.txt', description: 'Location of the file containing the list of target hostnames')
}
...
In the environment block, read the contents of the hostnames.txt file into a variable:
This will perform the backup operation on each hostname listed in the hostnames.txt file. Note that you can modify the HOSTNAMES_FILE parameter to point to a different file if needed.
I don’t understand, why hostname is not resolved and why the Pipeline fails?
+ cat hostnames.txt doesn’t show the content in the build console
URL: https://[:1234/api/backup doesn’t contain the hostname
It throws one exception and it’s not easy to understand in which line the cause is
...
[Pipeline] Start of Pipeline
[Pipeline] echo
20230403_053429
[Pipeline] node
Running on Jenkins in /jenkinsdata/example/main/workspace
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Checkout SCM)
[Pipeline] checkout
...
[Pipeline] }
[Pipeline] // stage
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Backup)
[Pipeline] withCredentials
Masking supported pattern matches of $BACKUP_PASSWORD
[Pipeline] {
[Pipeline] sh
+ cat hostnames.txt
[Pipeline] withEnv
[Pipeline] {
[Pipeline] timeout
Timeout set to expire in 2 min 0 sec
[Pipeline] {
[Pipeline] script
[Pipeline] {
[Pipeline] withCredentials
Masking supported pattern matches of $BACKUP_PASSWORD
[Pipeline] {
[Pipeline] }
[Pipeline] httpRequest
HttpMethod: POST
URL: https://[:1234/api/backup
Content-Type: application/json
Accept: application/zip
[Pipeline] }
[Pipeline] }
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // withCredentials
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
an exception which occurred:
in field com.cloudbees.groovy.cps.impl.ForInLoopBlock$ContinuationImpl.itr
in object com.cloudbees.groovy.cps.impl.ForInLoopBlock$ContinuationImpl@7c90a4cf
in field com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.target
in object com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl@3203f900
in field com.cloudbees.groovy.cps.impl.LoopBlockScopeEnv.continue_
in object com.cloudbees.groovy.cps.impl.LoopBlockScopeEnv@71263409
in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@6df14628
in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@269571d3
in field com.cloudbees.groovy.cps.impl.CpsClosureDef.capture
in object com.cloudbees.groovy.cps.impl.CpsClosureDef@1bc342e4
in field com.cloudbees.groovy.cps.impl.CpsClosure.def
in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@502d0610
in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@72c07282
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@72c07282
Caused: java.io.NotSerializableException: java.util.ArrayList$Itr
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:274)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1080)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1080)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1080)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:341)
at java.base/java.util.HashMap.internalWriteEntries(HashMap.java:1858)
at java.base/java.util.HashMap.writeObject(HashMap.java:1412)
at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:89)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:199)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1089)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:116)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.lambda$writeObject$1(RiverWriter.java:144)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:331)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:143)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:577)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:554)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgramIfPossible(CpsThreadGroup.java:537)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:461)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:330)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:294)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
at jenkins.util.ErrorLoggingExecutorService.lambda$wrap$0(ErrorLoggingExecutorService.java:51)
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:829)
GitHub has been notified of this commit’s build result
Finished: FAILURE