Search code examples
jenkinsgroovyjenkins-pipeline

Jenkins pipeline - getting a security error, how can I prevent the error from being raised?


I'm writing an Android build prcoess in Jenkins pipeline as a code. The relevant portion of the script is:

def notifyStarted() {
  // send to Slack
  slackSend (channel: '#slack-test', color: 'warning', message: "STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
def get_current_time_date() {
    Date date = new Date();   // given date
    Calendar calendar = GregorianCalendar.getInstance(); // creates a new calendar instance
    calendar.setTime(date);   // assigns calendar to given date
    TIMEH = calendar.get(Calendar.HOUR_OF_DAY); // gets hour in 24h format
    TIMEM = calendar.get(Calendar.MINUTE);
    TIMES = calendar.get(Calendar.SECOND);
    newdate = date.format( 'yyyy-MM-dd' );
    def result = newdate + '%' + TIMEH + ':' + TIMEM + ':' + TIMES
    result
}
// Mixpanel parameters

// End of Mixpanel parameters

node ('master') {
    notifyStarted()
    sh '( git reset --hard; git clean -fxd; git tag -d $(git tag) ) &>/dev/null || true'
    checkout scm
    MP_VERSION_NAME = sh '(git tag | grep '^[0-9]' | tail -n 1)'
    MP_API_KEY = "cXXXXXXXXXf"
    MP_API_SECRET = "4XXXXXXXXX4"
    MP_EXPIRE = "1588896000"
    MP_APP_PLATFORM = "Android"
    MP_BASE_URL = "http://mixpanel.com/api/2.0/annotations/create?"
    //RELEASE_DATE =  get_current_time_date()
    MP_RELEASE_NOTES = ""
    DESCRIPTION = "${MP_APP_PLATFORM}%v${MP_VERSION_NAME}${MP_RELEASE_NOTES}"
    REQUEST_URL = "api_key=${MP_API_KEY}&date=${RELEASE_DATE}&description=${DESCRIPTION}&expire=${MP_EXPIRE}"
    REQUEST_URL_NO_AMPERSAND = REQUEST_URL.replaceAll('&','')
    REQUEST_URL_API_SECRET = "${REQUEST_URL_NO_AMPERSAND}${MP_API_SECRET}"
    SIGNATURE = "md5 -q -s ${REQUEST_URL_API_SECRET}".execute().text
    CURL_COMMAND = "${MP_BASE_URL}${REQUEST_URL}&sig=${SIGNATURE}".replaceAll(' ','%20')
    def cwd = pwd()
    stage ('Compilation environement preparation') {
        // Build parameters
        NDK_VER="r12b"
        SDK_VER="r24.4.1"
        GRADLE_USER_HOME="${cwd}/.gradle"
        NDK_DIR="${GRADLE_USER_HOME}/android-ndk-${NDK_VER}"
        SDK_DIR="${GRADLE_USER_HOME}/android-sdk-linux"
        SDK_TOOLS="${SDK_DIR}/tools"
        AAPT="${SDK_DIR}/build-tools/23.0.3"

When running the build, I get the following error:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified method java.lang.String xor java.util.ArrayList
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:113)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:149)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:146)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:16)
    at WorkflowScript.run(WorkflowScript:30)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:48)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
    at sun.reflect.GeneratedMethodAccessor243.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.CollectionLiteralBlock$ContinuationImpl.dispatch(CollectionLiteralBlock.java:55)
    at com.cloudbees.groovy.cps.impl.CollectionLiteralBlock$ContinuationImpl.item(CollectionLiteralBlock.java:45)
    at sun.reflect.GeneratedMethodAccessor244.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:50)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
    at sun.reflect.GeneratedMethodAccessor243.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
    at com.cloudbees.groovy.cps.Next.step(Next.java:58)
    at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
    at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:163)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:324)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:78)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:236)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:224)
    at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:63)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
    at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
    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:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Finished: FAILURE

I believe the issue has something to do with the get_current_time_date function but I'm not sure how.

I've read about the error on the internet and found that I can go to Jenkins -> Manage Jenkins -> In-process Script Approval and approve certain code runs but how can I prevent this from happening? I'm not sure which code (out of 3) or which signature (out of 3) are the ones I should approve and in any case I want the pipeline to be able to run automatically, without human intervention.

Any idea what causes this error?


Solution

  • As you mentionned, you need to manually approve some methods signatures by doing it in Jenkins -> Manage Jenkins -> In-process Script Approval. It is a security system that sandboxes Groovy code execution so you don't execute dangerous/malicious code. You can't really avoid it, however you will need to approve each signature just once, not at every run.

    In short, approve manually the signatures until you have treated them all, and then you should be fine.