GitHub Actions provides access to all repository secrets through the secrets context. Using toJSON(secrets) serializes
and exposes the complete set of repository secrets to a workflow step.
When the full secrets context is serialized using toJSON(secrets) or a similar expression and passed to a job or step,
every secret in the repository becomes accessible in that context. This increases the attack surface: any vulnerability in the job or step — including
a compromised third-party action — can compromise all secrets rather than just the ones the job actually needs.
A single vulnerability in one workflow step can expose secrets that are entirely unrelated to that step’s purpose. Repository-wide credentials such as deployment keys, cloud provider tokens, or third-party API keys may all be extracted by an attacker who can influence only a small part of the workflow.
name: Example
on:
pull_request:
branches: [ main ]
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Example Step
env:
SECRETS: ${{ toJSON(secrets) }} # Noncompliant
run: |
example-command "$SECRETS"
name: Example
on:
pull_request:
branches: [ main ]
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Example Step
env:
API_KEY: ${{ secrets.API_KEY }}
run: |
example-command "$API_KEY"