ci/cd dangers
during a recent assessment of some ci/cd pipelines at work, i ran into a scenario where custom github actions were implemented to perform infrastructure as code (iac) scans against commits in the repo.
PASS ┌─────────┐ ┌────────┐
┌──────│ MERGE ├───►│ DEPLOY │
┌──────────┐ ┌──────────┐ │ └─────────┘ └────────┘
│PR OPENED ├────►│IAC SCANS ├──┤
└──────────┘ └──────────┘ │ ┌─────────┐
└──────│ BLOCK │
FAIL └─────────┘
the pipeline was pretty straightforward and just did some basic checks against the pull request to ensure that code standards are met and basic security issues (e.g. hardcoded creds) were not present. the pipeline used snyk/actions to perform an initial scan, then followed up with a custom action which was basically just a wrapper around wizcli.
a look at wizcli
wizcli is a tool to help devsecops teams integrate security into deployment pipelines and enforce best practices. while it has a few more use cases beyond iac scans, that is out of scope for this post. wiz allows you to define custom scan profiles with various thresholds for findings, which can influence whether a scan passes or fails. templates are defined in the web console, then specified using a cli arg in wizcli. the action code looked something like this, where the policy var is pulled from a repo variable and passed to the action, then scanCmd is passed to a shell with node's child_process() function.
let scanCmd = "./wizcli iac scan";
if (policy) {
scanCmd += ` --policy "${policy}"`
}
scope creep !!!
github has three (3) scope levels for variables used in actions. this is very useful as it allows organizations to manage configurations for development teams at the enterprise and organization levels. while useful, a common oversight when establishing ci/cd guardrails is that repository variables are only editable by repository owners.
note: in environments i have seen, the repository owner role is typically held by members of the devsecops team, not members of the development team. this leads to a false assumption that the repository variables are adequately protected from unauthorized changes


profit
now going back to this... "${policy}" the final command would be:
./wizcli iac scan --policy "IaC Scan Policy"
we can clearly see how this is a problem. anyone with control of this variable can compromise the action to exfiltrate secrets, access additional resources, or even move laterally to on-prem or cloud environments. in reality, anything is possible it truly just depends on the pipeline configuration.
a good starting point is to enumerate the environment vars in the action runner like so:

opsec considerations
- repository variable edits are not covered by typical mfa methods such as branch protection or pull request required reviews, therefore can be be written to with minimal noise
le fin
while not super complex and potentially very niche, i hope this helps in any future assessments. keep an eye out for those overlooked configurations :)