mediumCWE-269OWASP A01:2021

Overly Permissive Workflow Permissions

GitHub Actions workflows with permissions: write-all or no explicit permissions block grant the GITHUB_TOKEN excessive access, allowing a compromised step to modify code, create releases, write packages, or change repository settings.

How It Works

Every GitHub Actions workflow run receives a GITHUB_TOKEN with permissions scoped to the repository. By default (for repositories created before February 2023), this token has read and write access to all repository scopes: contents, packages, issues, pull-requests, deployments, and more. If any step in the workflow is compromised (via a supply chain attack on an action, script injection, or dependency confusion), the attacker inherits all these permissions. They can push code to any branch, create releases with malicious artifacts, write to GitHub Packages, or modify issues and PRs. GitHub introduced fine-grained permissions to limit the GITHUB_TOKEN to only the scopes a workflow actually needs.

Vulnerable Code
# BAD: no permissions block = default read-write to everything
name: CI
on: [push]
# No permissions block -- GITHUB_TOKEN gets full read-write access
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test
---
# Also BAD: explicitly granting write-all
name: CI
on: [push]
permissions: write-all
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test  # only needs read access, but has write-all
Secure Code
# GOOD: minimal permissions at workflow and job level
name: CI
on: [push]
permissions:
  contents: read  # only what's needed at workflow level
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test
  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    permissions:
      contents: read
      deployments: write  # only this job needs deploy permission
    steps:
      - uses: actions/checkout@v4
      - run: ./deploy.sh

Real-World Example

In 2022, the GitHub Actions team disclosed that workflows without explicit permissions blocks were a major risk surface. Several supply chain attacks exploited the default write-all GITHUB_TOKEN to push malicious code or publish tainted packages. GitHub changed the default for new repositories to read-only and introduced the permissions key specifically to address this attack vector.

How to Prevent It

  • Set permissions: read-all or permissions: {} at the workflow level and grant specific permissions only to jobs that need them
  • Change the default GITHUB_TOKEN permissions to read-only in your organization's Settings > Actions > General
  • Use job-level permissions blocks to scope each job's GITHUB_TOKEN to the minimum required access
  • Audit all workflow files for missing permissions blocks or overly broad permissions using actionlint or GitHub's security overview

Affected Technologies

GitHub ActionsNode.jsPythonDocker

Data Hogo detects this vulnerability automatically.

Scan Your Repo Free

Related Vulnerabilities