ghtier

Edition 2026-Q4 · reviewed 11 October 2026 · next review 15 January 2027 · methodology

GitHub threat landscape

Attacks on GitHub in 2026 are faster and more automated than the frameworks written to describe them. Campaigns scan all of public GitHub for one weak workflow, push credential stealers into thousands of repositories in an afternoon, and spread through package registries with tokens taken from the last victim. This page follows those campaigns, maps every incident on ghtier to OWASP CI/CD and NIST SP 800-204D, and points at the controls that would have broken them.

Why access in GitHub is hard to keep track of

GitHub grants access in more ways than most teams keep track of. A person can get write access to a repository through the organization's base permission, a team, a direct invite, a custom role or by being an owner. A workflow gets it from its GITHUB_TOKEN, an App from its installation, and a laptop from a classic token someone created three years ago and never revoked.

Each of those speaks its own language. Classic tokens use scopes, fine-grained tokens and Apps use permissions, people get roles, machines use keys, and settings decide which of them is allowed at all. Pushing to the default branch can be allowed by any of them, and blocked by a ruleset that some of them can bypass.

The map keeps growing. New features such as coding agents, rulesets, custom properties and artifact attestations bring new permissions and settings, and the older ways of granting access stay for compatibility. ghtier reads GitHub's permission, role and scope data every week and records what changed. An attacker only needs one path through it, which is what the rest of this page is about.

  1. Which GitHub?5setups
    • Free
    • Team
    • Enterprise Cloud
    • EMU
    • Server
  2. How was it given?25ways to grant access
    • 11 organization
    • 5 workload
    • 3 enterprise
    • 3 user
    • 3 application
  3. Who is the holder?26built-in roles
    • 147 role actions in GitHub's tables
    • 70 custom role permissions
  4. What do they hold?61token types, scopes and keys
    • 6 token types
    • 41 classic scopes
    • 14 keys and secrets
  5. What can it do?190permission levels
    • 104 permissions
    • 66 repository
    • 76 organization
    • 26 enterprise
    • 22 user
23 policies, grants and outside systems (SSO, IP allow list, PAT policy, rulesets, cloud trust) sit across all five layers and decide which of them are allowed at all. The same access is described in 5 different vocabularies: scopes, permissions, roles, keys and settings.
Counted from ghtier's own data at build time. GitHub's permission, role and scope tables are refreshed every week.

How attacks flow

Every incident on ghtier, from the way the attacker got in to what they went after, using the attack paths. Colour shows the plane the incident hit: control (settings, identity, policy), data (code, secrets, workflows, packages), both, or the GHES platform itself.
31 incidents, 81 pathsControlControl and dataDataPlatformWay in not confirmed
Show as a table
Way inWent afterPlaneIncidents
Member with write accessTake over the GHES appliancePlatformCVE-2026-3854: push-option metadata RCE
Leaked tokenSubmit malicious codeControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Leaked tokenSubmit malicious codeDataDependabot impersonation, GhostAction
Leaked token (not confirmed)Submit malicious codeDataMegalodon: mass backdooring of CI workflows
Leaked tokenPoint a release tag at a bad commitDatatj-actions/changed-files supply-chain compromise (CVE-2025-30066), TeamPCP tag force-overwrite campaign
Leaked tokenSteal CI secrets and tokensControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Leaked tokenSteal CI secrets and tokensDataDependabot impersonation, tj-actions/changed-files supply-chain compromise (CVE-2025-30066), ArtiPACKED artifact token leakage, GhostAction
Leaked token (not confirmed)Steal CI secrets and tokensDataMegalodon: mass backdooring of CI workflows
Leaked tokenPoison the build or published packageControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Leaked tokenPoison the build or published packageDataTeamPCP tag force-overwrite campaign
Leaked token (not confirmed)Poison the build or published packageDataMegalodon: mass backdooring of CI workflows
Leaked tokenRead or expose private codeControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Leaked tokenRead or expose private codeDataMercedes-Benz source code exposure
Leaked tokenKeep accessControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Leaked token (not confirmed)Keep accessDataMegalodon: mass backdooring of CI workflows
Phished or hijacked accountSubmit malicious codeControlOAuth consent phishing at scale
Phished or hijacked accountSubmit malicious codeControl and dataSalesloft Drift GitHub → AWS pivot
Phished or hijacked account (not confirmed)Submit malicious codeControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Phished or hijacked account (not confirmed)Delete code or cover tracksControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Phished or hijacked account (not confirmed)Point a release tag at a bad commitControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Phished or hijacked accountSteal CI secrets and tokensControl and dataCircleCI session-cookie theft, Salesloft Drift GitHub → AWS pivot
Phished or hijacked account (not confirmed)Steal CI secrets and tokensControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Phished or hijacked accountPoison the build or published packageControl and dataToptal repo-visibility flip and wiper
Phished or hijacked account (not confirmed)Poison the build or published packageControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Phished or hijacked accountRead or expose private codeControlOAuth consent phishing at scale
Phished or hijacked accountRead or expose private codeControl and dataToptal repo-visibility flip and wiper, Salesloft Drift GitHub → AWS pivot
Phished or hijacked accountKeep accessControlOAuth consent phishing at scale
Phished or hijacked accountKeep accessControl and dataSalesloft Drift GitHub → AWS pivot
Compromised GitHub App or OAuth integrationSubmit malicious codeDataGitHub App installation token abuse
Compromised GitHub App or OAuth integrationRead or expose private codeControl and dataHeroku / Travis CI OAuth token theft
Untrusted input reaches a privileged workflowSubmit malicious codeDatahackerbot-claw autonomous agent RCE
Untrusted input reaches a privileged workflowDelete code or cover tracksControl and dataNx "s1ngularity"
Untrusted input reaches a privileged workflowSteal CI secrets and tokensControl and dataNx "s1ngularity"
Untrusted input reaches a privileged workflowSteal CI secrets and tokensData"Pwn requests": pull_request_target & workflow_run, Ultralytics build cache poisoning, Self-hosted runner takeovers (PyTorch and others), hackerbot-claw autonomous agent RCE, Actions cache poisoning (Angular, TanStack), prt-scan: automated pull_request_target attacks
Untrusted input reaches a privileged workflowPoison the build or published packageControl and dataNx "s1ngularity"
Untrusted input reaches a privileged workflowPoison the build or published packageDataUltralytics build cache poisoning, Self-hosted runner takeovers (PyTorch and others), Actions cache poisoning (Angular, TanStack)
Untrusted input reaches a privileged workflowRead or expose private codeControl and dataNx "s1ngularity"
Compromised Action or packageSubmit malicious codeControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Compromised Action or package (not confirmed)Submit malicious codeControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Compromised Action or package (not confirmed)Delete code or cover tracksControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Compromised Action or package (not confirmed)Point a release tag at a bad commitControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Compromised Action or packagePoint a release tag at a bad commitDatatj-actions/changed-files supply-chain compromise (CVE-2025-30066), TeamPCP tag force-overwrite campaign
Compromised Action or packageSteal CI secrets and tokensControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Compromised Action or package (not confirmed)Steal CI secrets and tokensControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Compromised Action or packageSteal CI secrets and tokensDatatj-actions/changed-files supply-chain compromise (CVE-2025-30066)
Compromised Action or packagePoison the build or published packageControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Compromised Action or package (not confirmed)Poison the build or published packageControl and dataChainDrop: a hijacked maintainer account publishes through trusted publishing
Compromised Action or packagePoison the build or published packageDataTeamPCP tag force-overwrite campaign
Compromised Action or packageRead or expose private codeControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Compromised Action or packageKeep accessControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Compromised developer tool or extensionSubmit malicious codeControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Compromised developer tool or extensionDelete code or cover tracksDataGlassWorm: editor extensions that steal GitHub tokens and force-push
Compromised developer tool or extensionSteal CI secrets and tokensControl and dataCircleCI session-cookie theft, Shai-Hulud self-propagating worm (1.0 & 2.0)
Compromised developer tool or extensionPoison the build or published packageControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Compromised developer tool or extensionPoison the build or published packageDataGlassWorm: editor extensions that steal GitHub tokens and force-push
Compromised developer tool or extensionRead or expose private codeControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Compromised developer tool or extensionRead or expose private codeDataGitHub's internal repositories taken through a VS Code extension
Compromised developer tool or extensionKeep accessControl and dataShai-Hulud self-propagating worm (1.0 & 2.0)
Prompt injection into an AI agentRead or expose private codeDataGitHub MCP / agentic token breadth
Vulnerability in GitHub Enterprise ServerTake over the GHES appliancePlatformCVE-2024-4985: SAML auth bypass, CVE-2025-11578: pre-receive hook symlink escape, CVE-2025-3509: pre-receive hook RCE via port reuse, CVE-2026-3854: push-option metadata RCE, CVE-2024-1374: Management Console template injection, CVE-2022-23732: Management Console path traversal / CSRF bypass

OWASP CI/CD risks over time

Incidents per OWASP CI/CD risk, by the year they were first seen. One incident can count under several risks. The last column counts the 12 months up to 11 October 2026, from 11 October 2025. See also the NIST SP 800-204D crosswalk.

Where the frameworks are silent

What the 2026 campaigns rely on that OWASP CI/CD (2022) and NIST SP 800-204D (2024) cover only in part, or not at all.

Developer machines and IDE extensions

OWASP has no category for the developer's own machine. NIST names securing CI/CD clients as one step of its implementation strategy (section 5.3) but sets no requirements for it. Extensions, local tools and the tokens stored next to them fall between the two.

Worms that publish with stolen tokens

NIST's supply chain model has propagation as a stage, and CICD-SEC-3 covers dependency chain abuse. Neither gives controls for breaking the loop of stolen token, malicious publish, next victim: no long-lived registry tokens, publishing only from a reviewed workflow, and a cooldown before new versions are installed. Trusted publishing helps, but a hijacked maintainer account can still trigger it, as ChainDrop did.

Speed and scale

The frameworks treat each misconfiguration on its own: does the control exist or not. Campaigns in 2026 scan all of public GitHub for one misconfiguration and exploit it within hours, so how fast a fix is rolled out across every repository matters as much as whether the control exists.

Incidents that fit the OWASP list only in part or not at all: CircleCI session-cookie theft (partial), GitHub's internal repositories taken through a VS Code extension (no fit), GlassWorm: editor extensions that steal GitHub tokens and force-push (partial), GitHub MCP / agentic token breadth (partial), Nx "s1ngularity" (partial), Shai-Hulud self-propagating worm (1.0 & 2.0) (partial).

Controls that break the most current campaigns

Checklist items ranked by how many incidents first seen in the last 12 months they would have broken at least one step of, then by all incidents. A step counts when the item is listed as a fix for an attack path technique used in the incident. Breaking one step does not mean the incident would have been prevented.
  1. 15 recent · 8 all time
  2. 24 recent · 9 all time
  3. 34 recent · 7 all time
  4. 44 recent · 6 all time
  5. 54 recent · 6 all time
  6. 63 recent · 10 all time
  7. 73 recent · 9 all time
  8. 83 recent · 8 all time
  9. 93 recent · 6 all time
  10. 103 recent · 6 all time

Timeline

Every incident by the date it was first seen. Ongoing campaigns run to the review date.

2021

2022

2023

2024

2025

2026

Sources

Frameworks

Annual reports

GitHub's own guidance

Incident write-ups (88)

Methodology

  • An incident is a public, sourced case of GitHub access being abused: a named campaign, a vulnerability class with real victims, or a GitHub Enterprise Server flaw. All 31 are on the incidents page.
  • Each incident is tagged with its way in and what the attacker went after (from the attack paths), the OWASP CI/CD risks and NIST SP 800-204D sections it touches, the plane it hit, and the date it was first seen. The counts on this page are computed from those tags when the site is built.
  • The framework mappings are ghtier's own reading, not OWASP's or NIST's. They are marked for review until confirmed. Trends and gaps are editorial.
  • Time windows count back from the review date (11 October 2026), not from today, so the page does not change between reviews. Where only a month is known, the first of the month is used.
  • The page is reviewed every quarter: new incidents are added, ongoing ones updated, and trends with no incident in the window retired.