GITHUB_ENV can be dangerous to use, particularly if it's used in pull_request_target, workflow_run, or other triggers than run in the parent repo context but can be triggered by an untrusted third party.
In particular: if the attacker can control the environment variable (or add multiple new variables), they can typically achieve code execution (via LD_PRELOAD, or language-specific environment variables).
This can manifest in unintuitive or unusual ways, e.g.:
echo "pr_number=$(cat NR)" >> $GITHUB_ENV
if NR contains multiple lines, each gets added to the environment.
Or even:
env:
TITLE: ${{ github.event.pull_request.title }}
run: |
message=$(echo "$TITLE" | grep -oP '[{\[][^}\]]+[}\]]' | sed 's/{\|}\|\[\|\]//g')
echo "message=$message" >> $GITHUB_ENV
...since grep -P will cause each match to receive a new line, meaning that TITLE='[benign][LD_PRELOAD=...]' will inject the latter as an environment variable as well.
One wrinkle with flagging these is noisiness: GITHUB_ENV use in the context of pull_request and other "safe" triggers can result in code injection, but the attacker has no secret or otherwise privileged access to the workflow. As such, a new audit here should only flag on triggers that could allow external, privileged, code execution.
h/t @Ninja3047
Refs:
GITHUB_ENVcan be dangerous to use, particularly if it's used inpull_request_target,workflow_run, or other triggers than run in the parent repo context but can be triggered by an untrusted third party.In particular: if the attacker can control the environment variable (or add multiple new variables), they can typically achieve code execution (via
LD_PRELOAD, or language-specific environment variables).This can manifest in unintuitive or unusual ways, e.g.:
if
NRcontains multiple lines, each gets added to the environment.Or even:
...since
grep -Pwill cause each match to receive a new line, meaning thatTITLE='[benign][LD_PRELOAD=...]'will inject the latter as an environment variable as well.One wrinkle with flagging these is noisiness:
GITHUB_ENVuse in the context ofpull_requestand other "safe" triggers can result in code injection, but the attacker has no secret or otherwise privileged access to the workflow. As such, a new audit here should only flag on triggers that could allow external, privileged, code execution.h/t @Ninja3047
Refs: