@rafaelgss tech blog

Securing Your Github Actions

GitHub Actions (GHA) has become a critical tool for Open Source projects aiming to build reliable and customizable Continuous Integration (CI) and Continuous Deployment/Delivery (CD) pipelines.

GHA is not just powerful—it’s also a potential security vector if misused or misconfigured. Below is a list of common vulnerabilities and practical recommendations to secure your workflows.

1. Code Injection

Inputs like PR titles or issue comments can be manipulated to inject malicious code if not properly sanitized.

Risky fields:

  • event.issue.title
  • event.issue.body
  • event.pull_request.title
  • event.pull_request.body
  • event.review.body
  • event.comment.body

Example:

- name: Check title
  run: |
    title="${{ github.event.issue.title }}"
    if [[ ! $title =~ ^.*:\ .*$ ]]; then
      echo "Bad issue title"
      exit 1
    fi

Recommendation: Always treat these inputs as untrusted. Sanitize or validate all user-controlled data before use.

2. Environment Variables

Some environment variables can be abused to alter job behavior or exfiltrate data.

Examples:

  • NODE_OPTIONS – disallowed by default
  • BASH_ENV – can override subsequent runs
  • LD_PRELOAD – allows loading attacker-controlled code
  • HTTPS_PROXY – can redirect secrets to external hosts

About GITHUB_TOKEN:

  • Short-lived and scoped per job
  • Permissions vary by event trigger
  • Stored on disk after checkout unless disabled
- uses: actions/checkout@v4
  with:
    persist-credentials: false

Recommendation:

  • Limit environment variable use to trusted inputs.
  • Restrict GITHUB_TOKEN permissions to the minimum necessary.

3. pull_request_target Risks

The pull_request_target event exposes secrets and permissions to potentially untrusted code.

Key risks:

  • Secrets are available, even from forks
  • Subject to cache poisoning
  • Vulnerable to TOCTOU (Time-of-Check Time-of-Use) attacks

TOCTOU example: A PR author can push new commits after a label is applied, bypassing safeguards.

Recommendation:

  • Use pull_request + workflow_run with artifacts for forked PRs.
  • Use pull_request_target only for trusted contributors.
  • Always use head_sha when checking out code:
- uses: actions/checkout@v4
  with:
    ref: ${{ github.event.pull_request.head.sha }}

4. TOCTOU on pull_request.head.ref

pull_request.head.ref is mutable and can be changed between job scheduling and execution.

Recommendation:

Use pull_request.head.sha instead, which represents a fixed commit.

5. issue_comment TOCTOU

Using issue comments for triggering commands can lead to race conditions and misuse.

Recommendation:

Prefer label-based triggers combined with workflow_dispatch or manual approvals for safer control.

General Security Best Practices

  • Use short-lived and scoped GITHUB_TOKENs. They’re available in memory during job execution, so follow the principle of least privilege.
  • Pin actions to commit SHAs instead of tags. Tags are mutable and can be changed without notice.
  • Use CodeQL and GitHub Copilot to catch vulnerabilities early—when used properly, they’re powerful aids in securing your workflows.
  • Never trust artifacts blindly. Validate them explicitly before use.

Acknowledgments

Thanks to Carlos Fuentes for writting this article with me.