I do not have a tidy answer. The simple act of writing code in public now carries this, and I cannot stop turning over the obvious question.
What kind of world are we building?
It deserves more than a paragraph, and I will come back to it properly soon.
For now I only wanted to reach the people still carrying this, before something worse reaches them first. And there is one small thing you can do that helps everyone, not just you: if you were hit, cleaning your own repository removes one more live copy of this payload from the internet, and telling one other developer to check theirs reaches someone I cannot. That is how this gets smaller. If you are stuck at any point, say so, in the comments here or anywhere you can find me, and I will help.
Here is the full cleanup, step by step.
The full cleanup, step by step
The one rule above all: never let an affected repo run. No opening it in an AI editor, no npm install, no npm test. Work from a clone with nothing checked out.
1. Clone with no checkout.
git clone --no-checkout https://github.com/<you>/<repo>.git fix
cd fix
git fetch origin '+refs/heads/*:refs/remotes/origin/*'
2. Detect by the payload file, on every branch.
git for-each-ref --format='%(refname:short)' refs/remotes/origin | while read b; do
git cat-file -e "$b:.github/setup.js" 2>/dev/null && echo "INFECTED: $b"
done
3. Back up the evidence once.
git clone --mirror https://github.com/<you>/<repo>.git evidence.git
tar czf evidence.tar.gz evidence.git
4. Remove the malicious commit from each infected branch. For this worm the bad commit is usually the branch tip, so reset the branch to its parent:
git log -1 origin/<branch> -- .github/setup.js # confirm it is the latest commit
git push --force-with-lease origin <MALICIOUS_SHA>^:refs/heads/<branch>
Reset, not git revert: a revert leaves the payload retrievable at the old commit. (If a branch has real commits on top of the malicious one, do not use this as-is; rebase just the bad commit out instead.)
5. Purge the copies you cannot see. Because of the fork network a commit can stay reachable by its SHA after it is off every branch. Open a support ticket, give them the malicious SHAs, and ask them to garbage-collect and purge them via the sensitive-data removal process.
6. Rotate credentials properly (the step people miss). The way in is a harvested token, not your password, so 2FA does not stop it.
- Revoke the OAuth app authorization, not just individual tokens. GitHub stacks many tokens under one authorization (the GitHub CLI, for example); revoking single tokens or reinstalling your machine does not close it. Settings, Applications, Authorized OAuth Apps, revoke anything you do not fully trust and re-authorize fresh.
- If the GitHub UI errors out while you are revoking (the unicorn page), do not assume it worked. Come back when the platform is stable and confirm the app or token is actually gone. A failed revoke looks identical to a successful one.
- Rotate npm tokens and any cloud credentials (AWS, GCP, Azure) that ever sat on an affected machine.
Stay safe. You did nothing wrong.
Ionut-Cristian Florescu