|
| 1 | +# Environment Variable Injection |
| 2 | + |
| 3 | +## Description |
| 4 | + |
| 5 | +GitHub Actions allow to define environment variables by writing to a file pointed to by the `GITHUB_ENV` environment variable: |
| 6 | + |
| 7 | +This file contains lines in the `KEY=VALUE` format: |
| 8 | + |
| 9 | +```bash |
| 10 | +steps: |
| 11 | + - name: Set the value |
| 12 | + id: step_one |
| 13 | + run: | |
| 14 | + echo "action_state=yellow" >> "$GITHUB_ENV" |
| 15 | +``` |
| 16 | + |
| 17 | +It is also possible to define multiline variables by using the [following construct](https://en.wikipedia.org/wiki/Here_document): |
| 18 | + |
| 19 | +``` |
| 20 | +KEY<<{delimiter} |
| 21 | +VALUE |
| 22 | +VALUE |
| 23 | +{delimiter} |
| 24 | +``` |
| 25 | + |
| 26 | +```bash |
| 27 | +steps: |
| 28 | + - name: Set the value in bash |
| 29 | + id: step_one |
| 30 | + run: | |
| 31 | + { |
| 32 | + echo 'JSON_RESPONSE<<EOF' |
| 33 | + curl https://example.com |
| 34 | + echo EOF |
| 35 | + } >> "$GITHUB_ENV" |
| 36 | +``` |
| 37 | + |
| 38 | +If an attacker can control the values assigned to environment variables and there is no sanitization in place, the attacker will be able to inject additional variables by injecting new lines or `{delimiters}`. |
| 39 | + |
| 40 | +## Recommendations |
| 41 | + |
| 42 | +1. **Do not allow untrusted data to influence environment variables**: |
| 43 | + |
| 44 | + - Avoid using untrusted data sources (e.g., artifact content) to define environment variables. |
| 45 | + - Validate and sanitize all inputs before using them in environment settings. |
| 46 | + |
| 47 | +2. **Do not allow new lines when defining single line environment variables**: |
| 48 | + |
| 49 | + - `echo "BODY=$(echo "$BODY" | tr -d '\n')" >> "$GITHUB_ENV"` |
| 50 | + |
| 51 | +3. **Use unique identifiers when defining multi line environment variables**: |
| 52 | + |
| 53 | + ```bash |
| 54 | + steps: |
| 55 | + - name: Set the value in bash |
| 56 | + id: step_one |
| 57 | + run: | |
| 58 | + # Generate a UUID |
| 59 | + UUID=$(uuidgen) |
| 60 | + { |
| 61 | + echo "JSON_RESPONSE<<EOF$UUID" |
| 62 | + curl https://example.com |
| 63 | + echo "EOF$UUID" |
| 64 | + } >> "$GITHUB_ENV" |
| 65 | + ``` |
| 66 | + |
| 67 | +## Examples |
| 68 | + |
| 69 | +### Example of Vulnerability |
| 70 | + |
| 71 | +Consider the following basic setup where an environment variable `MYVAR` is set and used in subsequent steps: |
| 72 | + |
| 73 | +```yaml |
| 74 | +steps: |
| 75 | + - name: Set the value |
| 76 | + id: step_one |
| 77 | + env: |
| 78 | + BODY: ${{ github.event.comment.body }} |
| 79 | + run: | |
| 80 | + REPLACED=$(echo "$BODY" | sed 's/FOO/BAR/g') |
| 81 | + echo "MYVAR=$REPLACED" >> "$GITHUB_ENV" |
| 82 | +``` |
| 83 | + |
| 84 | +If an attacker can manipulate the value being set, such as through artifact downloads or user inputs, the attacker can potentially inject new environment variables. For example, they could write an issue comment like: |
| 85 | + |
| 86 | +```text |
| 87 | +FOO |
| 88 | +NEW_ENV_VAR=MALICIOUS_VALUE |
| 89 | +``` |
| 90 | + |
| 91 | +Likewise, if the attacker controls a file in the GitHub Actions Runner's workspace (eg: the workflow checkouts untrusted code or downloads an untrusted artifact) and the contents of that file are assigned to an environment variable such as: |
| 92 | +
|
| 93 | +```bash |
| 94 | +- run: | |
| 95 | + PR_NUMBER=$(cat pr-number.txt) |
| 96 | + echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV |
| 97 | +``` |
| 98 | +
|
| 99 | +An attacker could craft a malicious artifact that writes dangerous environment variables: |
| 100 | +
|
| 101 | +```bash |
| 102 | + - run: | |
| 103 | + echo -e "666\nNEW_ENV_VAR=MALICIOUS_VALUE" > pr-number.txt |
| 104 | + - uses: actions/upload-artifact@v4 |
| 105 | + with: |
| 106 | + name: pr-number |
| 107 | + path: ./pr-number.txt |
| 108 | +``` |
| 109 | +
|
| 110 | +### Exploitation |
| 111 | +
|
| 112 | +An attacker is be able to run arbitrary code by injecting environment variables such as `LD_PRELOAD`, `BASH_ENV`, etc. |
| 113 | +
|
| 114 | +## References |
| 115 | +
|
| 116 | +- [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions) |
| 117 | +- [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation) |
0 commit comments