CI/CD argument values should not flow directly into workflows
ID |
cicd_code_injection |
Severity |
critical |
Family |
CI/ CD Security |
Tags |
cicd-security, cicd_code_injection, reachable, security, supply-chain |
Description
CI/CD variables and parameters values should be treated as untrusted input. If these values flow into workflows, they could be interpreted as executable code.
A pretty interesting pipeline argument injection post was shared by the Microsoft devops team.
pool: { vmImage: 'windows-latest' }
steps:
- script: >
msbuild App1.sln
/p:platform="$(platform)" (1)
/p:configuration="$(configuration)" (1)
1 | In this Azure Devops pipeline example, both platform and configuration are provided at runtime by the user. At runtime, Azure Pipelines interpolates the script step with the values of variables surrounded by $( ). |
Security
String CI/ CD variables and parameters can be used for a variety of purposes, the system can’t quote, escape, or otherwise mangle them. That must be arranged by the code accepting the input.
You should ensure that these values do not flow directly into workflows, actions, API calls, or anywhere else where they could be interpreted as executable code.
For AzureDevops
, VariableGroups
are also a potential target for code injection attacks. If a user has permission to edit a variable group with any variables used in a pipeline script or Azure CLI task inline scripts, then the variable group can be used to inject script that is executed on the build runner. Either an existing variable can be edited or a new variable can be created with the same name as one hard-coded into the template.
Mitigation / Fix
These important guidelines should be followed:
-
To avoid pipelines tampering, they should be unaffected by user input; while providing arguments at runtime may be helpful for running different scenarios, it breaks the policy that workflows should not use user input and should be automated. So, when possible limit configurable pipelines as much as you can.
-
Use runtime (Azure Devops) or choice (GitHub) parameters to limit what inputs will be accepted.
-
For additional protection, use purpose-built tasks (Azure Devops) or actions (GitHub) which properly escape (or reject) malicious inputs.
-
Also, you can escape those inputs by using GH Workflow Env vars or Azure pipeline variables.
-
Other CI/CD systems, like GitLab pipelines, allow to use file variables for tools that need a file as input. The adversary may change the file path, but generally does not control the file contents and cannot abuse input variable for arbitrary code execution. In addition, the input variables can be "protected" so the variable is available only to pipelines that run on protected branches or tags.