Why is this an issue?

GitHub Actions workflows support special workflow commands that allow workflows to interact with the runner. These commands can be invoked by printing specially crafted messages to the standard output. For example, ::set-mask can be used to mask sensitive values in the workflow logs and ::error to terminate execution with a useful error message.

Two of such commands, ::set-env and ::add-path, allow setting arbitrary environment variables and modifying the system PATH for the subsequent workflow steps. In 2020, these commands were deprecated and disabled by default due to security concerns. However, ACTIONS_ALLOW_UNSECURE_COMMANDS environment variable can still be used to re-enable them.

If this environment variable is set, the runner will process ::set-env and ::add-path commands printed to the standard output. If an adversary can influence the content printed to the standard output (e.g., by injecting something into the build logs), they could use these commands to manipulate the runtime environment.

What is the potential impact?

When user-supplied values are used to manipulate environment variables, an attacker can supply carefully chosen values that cause the system to behave unexpectedly. This can be used to execute arbitrary commands as well as affect the behavior of other tools and scripts executed after the injection point. In most cases, this leads to arbitrary code execution on the system.

It is important to note, that these commands are triggered by printing to standard output. Therefore, this issue can be exploited if an attacker can influence the output of any command executed during the workflow.

The consequences of a successful attack can be severe and far-reaching:

Information disclosure

Attackers can extract sensitive information from the runner environment, including:

System compromise

Successful command injection allows attackers to:

Supply chain attacks

Compromised workflows can be used to:

Repository manipulation

Attackers may be able to:

The impact is particularly severe because GitHub Actions runners often have elevated privileges and access to sensitive resources, making them attractive targets for attackers.

How to fix it

To fix this issue, remove setting of the ACTIONS_ALLOW_UNSECURE_COMMANDS environment variable, and replace the use of ::set-env and ::add-path with their safe alternatives:

Code examples

Noncompliant code example

name: "Example"

jobs:
  set_env:
    runs-on: ubuntu-latest
    env:
      ACTIONS_ALLOW_UNSECURE_COMMANDS: true  # Noncompliant
    steps:
      - run: |
          echo "::set-env name=MESSAGE::hello"
      - run: |
          echo "Message: $MESSAGE"

Compliant solution

name: "Example"

jobs:
  set_env:
    runs-on: ubuntu-latest
    steps:
      - run: |
          echo "MESSAGE::hello" >> $GITHUB_ENV
      - run: |
          echo "Message: $MESSAGE"

Resources

Documentation

Articles & blog posts

Standards

Related rules