GitHub reports 3,800 internal repos breached via poisoned VS Code extension
Posts reported GitHub contained a breach after a poisoned VS Code extension compromised an employee device, with attacker claims around 3,800 internal repos matching the investigation. Related SHai-Hulud payload reports are pushing teams to audit `pull_request_target`, extension trust, and secret rotation.

TL;DR
- GitHub said an employee device was compromised through a poisoned VS Code extension, and WesRoth's incident summary says attacker claims of roughly 3,800 internal repositories were broadly consistent with GitHub's investigation.
- According to rohanpaul_ai's report, GitHub's stated blast radius was its own internal code rather than customer repositories, while WesRoth's recap says the company isolated the device, removed the malicious extension version, and rotated critical secrets.
- The same SHai-Hulud campaign appears to have hit open source maintainers too: aidenybai's security update said a malicious payload was reverted from
aidenybai/million, and aidenybai's follow-up tied it to repos usingpull_request_target. - aidenybai's linked note and the linked TanStack postmortem point to GitHub Actions workflow exposure as part of the pattern, not just a single bad editor install.
- badlogicgames' hardening thread shows how fast downstream toolmakers reacted: dependency pinning, shrinkwrapped transitive deps, disabled lifecycle scripts on self-update, and tighter review around new package scripts all shipped the same day.
You can read the linked TanStack postmortem, the Million incident note, and pi's terse hardening release thread. The weird part is how many separate trust surfaces show up at once: a poisoned VS Code extension at GitHub, pull_request_target abuse in maintainer repos, and package lifecycle scripts suddenly looking a lot less like boring plumbing.
GitHub's containment details
The core facts converged quickly. WesRoth's summary says GitHub detected and contained unauthorized access to internal repositories after an employee machine installed a poisoned VS Code extension, while rohanpaul_ai's report says the company treated the attacker claim of about 3,800 stolen repos as directionally consistent with its investigation.
Both posts also frame the boundary the same way: GitHub internal repositories were exposed, not customer repositories. That still matters because internal code can reveal service boundaries, test fixtures, operational assumptions, and secret-handling paths even when production credentials have already been rotated, a risk rohanpaul_ai's post surfaced explicitly.
The publicly described response was operational rather than speculative:
- isolate the compromised device, per WesRoth's summary
- remove the malicious extension version, per WesRoth's summary
- rotate critical secrets, per rohanpaul_ai's report
- continue log analysis and monitoring, per WesRoth's summary
One detail GitHub still had not disclosed in the evidence pool was the name of the poisoned extension, according to rohanpaul_ai's report.
SHai-Hulud's open source path
The adjacent maintainer reports make this look less like an isolated GitHub oddity and more like a reusable intrusion path. In aidenybai's security update, the Million maintainer said a malicious payload had been found and reverted, with risk limited to development environments that cloned the repo locally and opened it in VS Code or Claude Code.
The next post added the GitHub Actions angle. aidenybai's follow-up said the broader SHai-Hulud attack targeted repositories using pull_request_target, and the linked Million incident note points readers to more detail in the GitHub issue thread.
That lines up with the linked TanStack postmortem, which became the reference document people kept passing around in replies and follow-ups. Inside this evidence set, the repeated pattern is:
- compromise maintainer or workflow trust somewhere upstream
- land a malicious payload in a repository or package path
- trigger code execution in a developer environment rather than in a published artifact
- use that foothold to go after tokens, cloud credentials, or adjacent systems
That distinction matters for reading the blast radius correctly. aidenybai's post said npm consumers of the published package were not affected, which is a very different incident from a compromised package release hitting every downstream install.
Trust surfaces that suddenly matter
The fastest useful reaction came from teams treating this as a trust-surface inventory. badlogicgames' hardening thread lists a same-day package hardening pass for pi after what it calls a SHai-Hulud scare around the mistralai package.
The changes are concrete:
- cut dependencies to the minimum, per badlogicgames' hardening thread
- pin direct dependencies, per the same thread
- ship an npm shrinkwrap for transitive dependencies, per the same thread
- disable lifecycle scripts in
pi update --self, per the same thread - require explicit review for new dependency lifecycle scripts, per the same thread
- block unexpected lockfile changes pre-commit, per the same thread
- run scheduled npm audit and registry signature checks in GitHub, per the same thread
- keep 2FA on releases, per the same thread
Then badlogicgames' follow-up warning narrowed the distribution channel too: the project said it only publishes to npm under @earendil-works and to GitHub Releases for the self-contained Bun build. That is a small but sharp reminder that package manager sprawl is part of the attack surface, not just the code inside a repo.
The unresolved extension question
The most important missing fact is still mundane: which VS Code extension was poisoned. rohanpaul_ai's report says GitHub did not disclose the extension name, and none of the primary evidence here fills that gap.
That omission leaves two separate stories partially open. One is incident response inside GitHub. The other is ecosystem cleanup across editor marketplaces, forks, cloned repos, and local agent tools that execute repository code during development. aidenybai's post is unusually specific that local clones opened in VS Code or Claude Code were the risk surface in Million's case.
The result is a breach story where the missing noun matters almost as much as the repo count. Until the extension is named, the cleanest public evidence is still the shape of the chain: poisoned tool, compromised developer machine, internal code access, then a much broader scramble to lock down workflows that looked ordinary the day before.