Skip to content

Secrets exfiltration via `pull_request_target`

Critical
stephanebruckert published GHSA-h25v-8c87-rvm8 May 15, 2025

Package

actions spotipy-dev/spotipy (GitHub Actions)

Affected versions

4f5759dbfb4506c7b6280572a4db1aabc1ac778d

Patched versions

9dfb7177b8d7bb98a5a6014f8e6436812a47576f

Description

### Summary
Using pull_request_target on .github/workflows/integration_tests.yml followed by the checking out the head.sha of a forked PR can be exploited by attackers, since untrusted code can be executed having full access to secrets (from the base repo). By exploiting the vulnerability is possible to exfiltrate GITHUB_TOKEN and secrets SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET. In particular GITHUB_TOKEN which can be used to completely overtake the repo since the token has content write privileges.

Details

The pull_request_target in GitHub Actions is a major security concern—especially in public repositories—because it executes untrusted code from a PR, but with the context of the base repository, including access to its secrets.

  pull_request_target:
    types: [opened, synchronize, reopened]

Along with code checkout on head.sha, an attacker is able to control the code and change the workflow to execute random code.

      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.ref }}
          repository: ${{ github.event.pull_request.head.repo.full_name }}

PoC

An attacker has multiple injection point inside the workflow .github/workflows/integration_tests.yml.
By adding in the repo a malicious python package it's possible to install it via workflow pip install . and execute the malicious code.
To prove this is possible we did a test by adding a malicious packaged to extract the GITHUB_TOKEN. With the token extracted I was able to create a testing tag pga-v1.1.55 which has been deleted after 2 minutes.
Screenshot 2025-05-15 alle 17 53 09

Impact

Usually with GITHUB_TOKEN and write permissions, an attacker is able to completely overtake the repo.

GITHUB_TOKEN Permissions
  Actions: write
  Attestations: write
  Checks: write
  Contents: write
  Deployments: write
  Discussions: write
  Issues: write
  Metadata: read
  Models: read
  Packages: write
  Pages: write
  PullRequests: write
  RepositoryProjects: write
  SecurityEvents: write
  Statuses: write

Fix

We suggest to remove pull_request_target from all the workflows and more importantly to remove/fix it in all branches that contain it, or manage to use it properly without checking out untrusted code.
We also advice to properly set the GITHUB_TOKEN permissions properly based on that the workflow needs to do, restricting what it's not necessary.

Kindly reported by @AlbertoPellitteri and @darryk10

References

Severity

Critical

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

CVE ID

CVE-2025-47928

Weaknesses

Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component. Learn more on MITRE.

Credits