Using string-typed workflow_call inputs in GitHub Actions may lead to code injection in contexts like run: or script:.
Inputs declared as string should be treated with caution. Although workflow_call can only be triggered by other workflows (not directly by external users), the calling workflow may pass untrusted user input as arguments. Since the reusable workflow author has no control over the callers, these inputs may still originate from untrusted data.
Code injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token.
The best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not ${{ env.VAR }}).
It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.
The following example uses a workflow_call input directly in a run: step, which allows code injection if the caller passes untrusted data:
on:
workflow_call:
inputs:
title:
description: 'Title'
type: string
jobs:
greet:
runs-on: ubuntu-latest
steps:
- run: |
echo '${{ inputs.title }}'The following example safely uses a workflow_call input by passing it through an environment variable:
on:
workflow_call:
inputs:
title:
description: 'Title'
type: string
jobs:
greet:
runs-on: ubuntu-latest
steps:
- env:
TITLE: ${{ inputs.title }}
run: |
echo "$TITLE"- GitHub Security Lab Research: Keeping your GitHub Actions and workflows secure: Untrusted input.
- GitHub Docs: Security hardening for GitHub Actions.
- GitHub Docs: Reusing workflows.
- Common Weakness Enumeration: CWE-94: Improper Control of Generation of Code ('Code Injection').
- Common Weakness Enumeration: CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection').
- Common Weakness Enumeration: CWE-116: Improper Encoding or Escaping of Output.