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

Ability to whitelist steps in Jenkinsfiles while allowing all steps in global pipeline libraries

      We are attempting to block access to pipeline steps that we consider a security risk (e.g. the Kubernetes plugin steps) from user provided Jenkinsfiles, but allowing access to all the steps from global pipeline libraries. Ideally we would only allow access to steps within our global pipeline library.

      The only way we have come up with is to create StepListener extension. The extension uses reflection on the StepContext to check whether the step was executed via the Jenkinsfile or a global pipeline library.

      As I understand it, this is not considered good practice and may break in future.

      Is there some existing functionality to achieve what we need here or the possibility of extending the StepListener API to provide it?

       

          [JENKINS-69606] Ability to whitelist steps in Jenkinsfiles while allowing all steps in global pipeline libraries

          Matthew Walker created issue -

          Sam Gleske added a comment - - edited

          This would be a useful open source plugin.  Adding on, I would also like to not even necessarily allow all Vars or shared library steps.  In some cases, I develop a global step meant only for private use in the global shared pipeline library.  Not meant for use by users.

          Detecting a global var

          Here's some code which allows a dynamic var look up to see if a step is a core Jenkins step or a shared pipeline var.

          https://github.com/samrocketman/jervis/blob/64d21aff1d08ae58cc310cae5e868a4923b4bcab/vars/hasGlobalVar.groovy#L33

          It would be great if the whitelist could also apply to global vars or have an option around global vars.

          Other necessary considerations

          I've found doing a basic AST review of a Jenkinsfile is not enough because a user can pull in a user shared library via the library step.  I think user shared libraries should be supported so allowing steps in a user shared library is useful to be automatically white listed without having to explicitly state allowed steps.

          This also means it is necessary for limitations around allowed steps also be applied to the contents of user shared libraries.

          Sam Gleske added a comment - - edited This would be a useful open source plugin.  Adding on, I would also like to not even necessarily allow all Vars or shared library steps.  In some cases, I develop a global step meant only for private use in the global shared pipeline library.  Not meant for use by users. Detecting a global var Here's some code which allows a dynamic var look up to see if a step is a core Jenkins step or a shared pipeline var. https://github.com/samrocketman/jervis/blob/64d21aff1d08ae58cc310cae5e868a4923b4bcab/vars/hasGlobalVar.groovy#L33 It would be great if the whitelist could also apply to global vars or have an option around global vars. Other necessary considerations I've found doing a basic AST review of a Jenkinsfile is not enough because a user can pull in a user shared library via the library step.  I think user shared libraries should be supported so allowing steps in a user shared library is useful to be automatically white listed without having to explicitly state allowed steps. This also means it is necessary for limitations around allowed steps also be applied to the contents of user shared libraries.
          Sam Gleske made changes -
          Component/s New: script-security-plugin [ 18520 ]

          Sam Gleske added a comment -

          Added script-security-plugin as a component.  This might be best a feature request in the script security plugin.  To enable a vars and steps allow or block list.

          Sam Gleske added a comment - Added script-security-plugin as a component.  This might be best a feature request in the script security plugin.  To enable a vars and steps allow or block list.

          Sam Gleske added a comment -

          mwinter69 shared with me some great resources from Gitter. I plan to implement and open source a plugin for this since this is a need I have.

          Potential extension points:

          Sam Gleske added a comment - mwinter69 shared with me some great resources from Gitter. I plan to implement and open source a plugin for this since this is a need I have. Potential extension points: https://javadoc.jenkins.io/plugin/workflow-api/org/jenkinsci/plugins/workflow/flow/GraphListener.html https://javadoc.jenkins.io/plugin/workflow-api/org/jenkinsci/plugins/workflow/flow/StepListener.html

          Sam Gleske added a comment -

          Another example, shell step https://github.com/jenkinsci/workflow-durable-task-step-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/ShellStep.java has a getFunction call which returns "sh" on its descriptor impl.

          Here's an example of sandbox usage.

          https://github.com/jenkinsci/workflow-durable-task-step-plugin/pull/110/files#diff-d41f0e79c6665d69c24339f2d6671f9a4f7e1e0457638614cd48c0a6a44ae4cb

          https://javadoc.jenkins.io/plugin/workflow-cps/org/jenkinsci/plugins/workflow/cps/CpsFlowDefinition.html CPS flow definition has isSandbox method. This could hypothetically be used to determine if a step was called by a global shared library or a user Jenkinsfile. Shared libraries are not sandboxed while user Jenkinsfiles are. I'll need to test more on this when I actually start implementing.

          Sam Gleske added a comment - Another example, shell step https://github.com/jenkinsci/workflow-durable-task-step-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/ShellStep.java has a getFunction call which returns "sh" on its descriptor impl. Here's an example of sandbox usage. https://github.com/jenkinsci/workflow-durable-task-step-plugin/pull/110/files#diff-d41f0e79c6665d69c24339f2d6671f9a4f7e1e0457638614cd48c0a6a44ae4cb https://javadoc.jenkins.io/plugin/workflow-cps/org/jenkinsci/plugins/workflow/cps/CpsFlowDefinition.html CPS flow definition has isSandbox method. This could hypothetically be used to determine if a step was called by a global shared library or a user Jenkinsfile. Shared libraries are not sandboxed while user Jenkinsfiles are. I'll need to test more on this when I actually start implementing.

          Sam Gleske added a comment - - edited

          Step implements getDescriptor so to get the step name via Groovy one would call ".descriptor.functionName"

          Sam Gleske added a comment - - edited Step implements getDescriptor so to get the step name via Groovy one would call ".descriptor.functionName"

          Sam Gleske added a comment -

          Sam Gleske added a comment - I have published a plugin https://github.com/samrocketman/restrict-steps-plugin and opened a hosting request https://github.com/jenkins-infra/repository-permissions-updater/issues/3391

          Sam Gleske added a comment -

          Global variables get invoked here. It would be nice if there was a Listener similar to StepListener to do some kind of pre-flight check before it is called.

          I also notice CpsWhitelist has it. Perhaps I could update the whitelist at runtime somehow to prevent users from calling the shared library steps.

          Currently, there's no easy way to determine if a step was called from a Global var (out of sandbox) or a user pipeline (in sandbox). I'm still researching.

          Sam Gleske added a comment - Global variables get invoked here . It would be nice if there was a Listener similar to StepListener to do some kind of pre-flight check before it is called. I also notice CpsWhitelist has it. Perhaps I could update the whitelist at runtime somehow to prevent users from calling the shared library steps. Currently, there's no easy way to determine if a step was called from a Global var (out of sandbox) or a user pipeline (in sandbox). I'm still researching.
          Sam Gleske made changes -
          Assignee New: Sam Gleske [ sag47 ]

            sag47 Sam Gleske
            matthewwalker Matthew Walker
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: