Threat Intel Report

Grafana Labs GitHub Security Breach: The Forensic Anatomy of a “Pwn Request” Exploitation

How an over-privileged pull_request_target trigger exposed private codebases supporting 25 million users, and the step-by-step audit to protect your environment.

By Threat Research Team

Quick Summary of the Breach

  • The Incident: On May 17, 2026, Grafana Labs disclosed that an unauthorized party obtained a privileged token and cloned portions of its private GitHub codebases.
  • The Vector: A classic “Pwn Request” vulnerability inside a GitHub Actions CI/CD workflow.
  • The Defense: Grafana’s internal canary tokens successfully triggered, notifying security responders instantly. No customer data or production systems were impacted.

In mid-May 2026, open-source observability leader Grafana Labs disclosed a targeted infiltration of their GitHub environment. With over 25 million active users and a enterprise customer base that includes tech powerhouses like Nvidia, Microsoft, Bloomberg, Anthropic, and Salesforce, a codebase compromise at Grafana represents a critical supply chain risk.

Fortunately, the blast radius was strictly isolated. Grafana Labs confirmed that customer systems, personal information, and live SaaS operations remained entirely untouched. However, the underlying exploit strategy highlights a critical vulnerability class: Pipeline Parasitism and CI/CD token theft. Here is exactly how the threat actor bypassed GitHub’s isolation boundaries—and how you can ensure your workflows aren’t vulnerable.

The Exploit Vector: Bypassing Boundaries with pull_request_target

The root cause of the infiltration was traced to a GitHub Actions workflow named pr-patch-check-event.yml within the grafana/grafana repository. This file was misconfigured to trigger on the pull_request_target event.

Under normal circumstances, standard pull_request triggers run inside an isolated runner using a read-only token, shielding the repository’s secrets from malicious public forks. However, the pull_request_target trigger runs in the context of the base repository, granting the workflow access to full write-access tokens and the base repository’s repository secrets.

By exploiting a combination of a “Pwn Request” (untrusted code execution) and unsafe parameter handling, the attacker executed the following sequence:

  1. Fork & Inject: The attacker forked the public Grafana repository, modified the code inside a pull request, and injected a malicious curl payload through raw shell interpolation.
  2. Privileged Token Generation: Because the workflow utilized the popular tibdex/github-app-token action, the malicious script generated a highly privileged GitHub App installation token.
  3. Data Exfiltration: The payload executed environment variable dumps, wrote them to a file, encrypted the file using a private key to evade traditional network-level detection, and exfiltrated the package.
  4. Fork Deletion: After securing the token, the attacker immediately deleted their public fork to obscure their footprint.
  5. Lateral Repetition: Equipped with the exfiltrated credential, the attacker initiated similar cloned workflows across four additional private repositories.

Extortion Attempt Refused

After cloning a portion of Grafana’s internal repositories, the threat actor attempted to extort the company, threatening public code releases in exchange for ransom. Aligned with FBI guidelines—which emphasize that paying ransoms incentivizes future cybercrime without guaranteeing data security—Grafana Labs firmly declined the extortion demands.

The Savior: How Canary Tokens Caught the Attacker

The threat actor’s run of stealth ended abruptly. Grafana had embedded thousands of inactive, decoy secrets—called **canary tokens**—directly into their codebases. The moment the attacker downloaded the codebase and attempted to validate or run one of these decoy tokens, the trap sprung. An alert was immediately dispatched to Grafana’s global security operations team, allowing them to instantly isolate the leak, invalidate the compromised credentials, and initiate forensic remediation.

Step-by-Step Defense: How to Audit Your GitHub Actions

To avoid becoming the next victim of Pipeline Parasitism, your security team must apply strict, zero-trust constraints across your CI/CD configurations. Implement the following remediation strategies based on OWASP security guidelines:

1. Restrict default GITHUB_TOKEN Permissions

By default, some legacy GitHub configurations grant read/write access to the default GITHUB_TOKEN. Force your workflows to declare permissions explicitly.

# Example of a Secure, Least-Privileged Workflow Configuration
name: Secure CI Pipeline
on:
  pull_request:
    branches: [ main ]

# Block all default token permissions globally
permissions:
  contents: read
  issues: none
  packages: none

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Securely
        uses: actions/checkout@v4
        with:
          persist-credentials: false # Prevents token exposure in memory

2. Eliminate Shell Injection Points

Never interpolate user-controlled variables (such as PR titles, branch names, or commit messages) directly into run scripts. Attackers can close your strings and run remote commands.

❌ VULNERABLE (Shell Interpolation) run: echo "Processing PR: ${{ github.event.pull_request.title }}"
✅ SECURE (Using Environment Variables)
run: echo "Processing PR: $PR_TITLE"
env:
  PR_TITLE: ${{ github.event.pull_request.title }}

3. Implement Mandatory Approvals for Public Forks

Ensure your organizational settings require explicit manual review from a repository administrator before any workflow is executed from a public contributor’s fork. This halts unauthorized code executions before they hit active runners.

Secure Your Pipelines Before Your Code Leaves Your Servers

Are you running workflows triggered by pull_request_target? Our security team compiled a comprehensive GitHub Actions Security Audit script that automatically scans your repositories for over-privileged permissions, unpinned action hashes, and vulnerable triggers.

Download the Complete GitHub Security Audit Kit

Leave a Reply

Your email address will not be published. Required fields are marked *

Inspired by this vision? Share it with a friend.