Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-37129

Sandbox RejectedAccessException when using docker.image.inside() stupidly

      Steps to reproduce:

      1. Start with a fresh Jenkins installation (reproduced on both 2.7.1 LTS and 2.16(
      2. Install suggested plugins
      3. Install CloudBees Docker Pipeline plugin (1.7)
      4. Create a Pipeline project with the snippet below
      5. Run Pipeline, see exception below.
      node {
        docker.image.inside('ubuntu:trusty') {
        }
      }
      
      org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject getProperty java.lang.String (org.jenkinsci.plugins.docker.workflow.Docker.image)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectMethod(StaticWhitelist.java:181)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor$11.reject(SandboxInterceptor.java:312)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:363)
      	at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
      	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:23)
      	at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:17)
      	at WorkflowScript.run(WorkflowScript:4)
      	at ___cps.transform___(Native Method)
      	at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:62)
      	at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
      	at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:54)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	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:32)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:29)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:29)
      	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:164)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:360)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:80)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:236)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:226)
      	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
      	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
      

      Note: The Pipeline project does, by default, have Groovy Sandbox checked (see screenshot). I have also reproduced this after restarting Jenkins to make sure there aren't any live-loading issues with the plugins.

          [JENKINS-37129] Sandbox RejectedAccessException when using docker.image.inside() stupidly

          R. Tyler Croy added a comment -

          So I have sobered up a little more and realized that my Pipeline script was wrong and I should have been invoking docker.image('ubuntu:trusty').inside instead.

          I am still leaving the ticket here because IMO there still is a usability bug around using the Docker Pipeline plugin provided DSL and the error messages shown.

          R. Tyler Croy added a comment - So I have sobered up a little more and realized that my Pipeline script was wrong and I should have been invoking docker.image('ubuntu:trusty').inside instead. I am still leaving the ticket here because IMO there still is a usability bug around using the Docker Pipeline plugin provided DSL and the error messages shown.

          Jesse Glick added a comment -

          script-security does not know for sure whether you just mistyped a method name (or, as in this case, omitted an argument) or were genuinely trying to call a Groovy dynamic method—which would never be allowed in the sandbox. It does include information about what you were apparently trying to call in the exception message, but perhaps it should expand the message to emphasize that this would be a routine consequence of such a mistake.

          Jesse Glick added a comment - script-security does not know for sure whether you just mistyped a method name (or, as in this case, omitted an argument) or were genuinely trying to call a Groovy dynamic method—which would never be allowed in the sandbox. It does include information about what you were apparently trying to call in the exception message, but perhaps it should expand the message to emphasize that this would be a routine consequence of such a mistake.

          This is a serious usability issue. I wasted some time falling into this trap in the last week.

          Kohsuke Kawaguchi added a comment - This is a serious usability issue. I wasted some time falling into this trap in the last week.

          Jesse Glick added a comment -

          As with the long list of things mentioned in https://github.com/kohsuke/groovy-sandbox/issues/7 it is tricky for SandboxInterceptor to figure out what the regular Groovy runtime would be calling were the call not intercepted. This is one of the more irritating consequences of that limitation. We would want to generate a MissingMethodException like the one you would normally get, that has various suggestions in it. Perhaps it suffices to just replace new RejectedAccessException("unclassified …") with a Missing*Exception, since these seem to do their own diagnostics. Needs testing.

          Jesse Glick added a comment - As with the long list of things mentioned in https://github.com/kohsuke/groovy-sandbox/issues/7  it is tricky for SandboxInterceptor to figure out what the regular Groovy runtime would be calling were the call not intercepted. This is one of the more irritating consequences of that limitation. We would want to generate a MissingMethodException like the one you would normally get, that has various suggestions in it. Perhaps it suffices to just replace new RejectedAccessException("unclassified …") with a Missing*Exception , since these seem to do their own diagnostics. Needs testing.

          Jesse Glick added a comment -

          Ah, missed that you had filed a PR. Please use assignee & status to indicate such things.

          Jesse Glick added a comment - Ah, missed that you had filed a PR. Please use assignee & status to indicate such things.

          Code changed in jenkins
          User: Kohsuke Kawaguchi
          Path:
          src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptor.java
          src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptorTest.java
          http://jenkins-ci.org/commit/script-security-plugin/950c4f444aa082ea0280a92f084004137ce0d900
          Log:
          JENKINS-37129 unclassified method vs MethodMissingException

          As an user, I don't always precisely remember what methods an object
          has, an I often end up making mistakes. From workflow-cps perspective,
          this results in trying to call a method that does not exist.

          This must result in MethodMissingException, just like normal Groovy
          interpretor. The code currently makes this a RejectedAccessException,
          making the user believe that the method exists but the access it not
          allowed.

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Kohsuke Kawaguchi Path: src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptor.java src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptorTest.java http://jenkins-ci.org/commit/script-security-plugin/950c4f444aa082ea0280a92f084004137ce0d900 Log: JENKINS-37129 unclassified method vs MethodMissingException As an user, I don't always precisely remember what methods an object has, an I often end up making mistakes. From workflow-cps perspective, this results in trying to call a method that does not exist. This must result in MethodMissingException, just like normal Groovy interpretor. The code currently makes this a RejectedAccessException, making the user believe that the method exists but the access it not allowed.

          Code changed in jenkins
          User: Kohsuke Kawaguchi
          Path:
          src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptor.java
          src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptorTest.java
          http://jenkins-ci.org/commit/script-security-plugin/1ff48ff222e6b2f659bfff8ac92399d4e31e6655
          Log:
          Merge pull request #134 from jenkinsci/MissingMethodException

          JENKINS-37129 unclassified method vs MethodMissingException

          Compare: https://github.com/jenkinsci/script-security-plugin/compare/819724526dd4...1ff48ff222e6

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Kohsuke Kawaguchi Path: src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptor.java src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/groovy/SandboxInterceptorTest.java http://jenkins-ci.org/commit/script-security-plugin/1ff48ff222e6b2f659bfff8ac92399d4e31e6655 Log: Merge pull request #134 from jenkinsci/MissingMethodException JENKINS-37129 unclassified method vs MethodMissingException Compare: https://github.com/jenkinsci/script-security-plugin/compare/819724526dd4...1ff48ff222e6

            kohsuke Kohsuke Kawaguchi
            rtyler R. Tyler Croy
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: