Coordinated Disclosure Timeline

  • 2026-08-19: The report was sent.
  • 2026-08-19: The report was accepted, and the workflow was deleted.

Summary

The API Diff Check workflow runs on pull_request_target, checks out a pull request’s merge ref, and then invokes the checkout-relative ./.github/actions/setup-go composite action. An external pull request author can modify that local action and execute arbitrary code in the privileged base-repository workflow. The job grants its GITHUB_TOKEN pull-requests: write and issues: write permissions. The attacker-controlled code can steal the repository-level ORG_REPO_TOKEN secret before the later conditional step that explicitly references it.

Project

DataDog/trivy repository

Tested Version

Observed on the default branch at commit 7acb5f6f095a11cb9911af5a0bc03aecc7c88f8f.

Details

PR-controlled local action executes in a privileged pull_request_target workflow (GHSL-2026-199)

The API Diff Check workflow runs for pull_request_target events when a pull request changes a Go file under pkg/ or rpc/. The workflow executes in the base repository context with write access to pull requests and issues:

on:
  pull_request_target:
    types: [opened, synchronize]
    paths:
      - 'pkg/**/*.go'
      - 'rpc/**/*.go'

permissions:
  contents: read
  pull-requests: write
  issues: write

The initial gate only checks whether GitHub considers the pull request mergeable. It does not establish trust in the pull request author or protect any file in the pull request tree.

The workflow then checks out the pull request merge ref into the default workspace and immediately invokes a local action from that checkout:

- name: Checkout
  uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
  with:
    ref: refs/pull/${{ github.event.pull_request.number }}/merge

- name: Set up Go
  uses: ./.github/actions/setup-go

Because actions/checkout replaces the workspace with the pull request merge tree, ./.github/actions/setup-go resolves to the pull request-controlled version of the composite action. A pull request can therefore add arbitrary shell steps to that action. The action runs in the privileged job and can access the job token through the github.token context.

The workflow later runs go-apidiff and, when it reports a major API change, invokes actions/github-script with ORG_REPO_TOKEN to request an organization team review (lines 160-178).

Impact

An unaffiliated fork contributor can execute arbitrary commands in a base-repository pull_request_target job. The code can use the workflow’s GITHUB_TOKEN to modify issues and pull requests, including labels, comments, and other state allowed by issues: write and pull-requests: write.

An attacker gains the private-resource and organization access granted to ORG_REPO_TOKEN, in addition to the job’s GITHUB_TOKEN permissions. The exact impact depends on the token’s configured scopes.

CWEs

  • CWE-829: Inclusion of Functionality from Untrusted Control Sphere

Resources

Credit

This issue was discovered and reported by GHSL team member @JarLob (Jaroslav Lobačevski).

Contact

You can contact the GHSL team at securitylab@github.com; please include a reference to GHSL-2026-199 in any communication regarding this issue.