GlassWorm hits 400+ GitHub repos, npm packages and VS Code/OpenVSX extensions
GlassWorm used stolen GitHub tokens to force-push malware into Python repos, poison npm packages and VS Code extensions. IOCs and checks for developers.

In March 2026, GlassWorm, a supply-chain campaign that steals developer credentials, came back in a larger wave covering GitHub repositories, npm packages and VS Code/OpenVSX extensions. It's a worm in the practical sense: tokens stolen from developer machines are used to push malicious code into those developers' own repositories, which infects the next set of developers who clone or install them. If you install packages straight from GitHub or run community editor extensions, this campaign applies to you.
What happened
GlassWorm was first reported in October 2025, when researchers found malicious VS Code and OpenVSX extensions that hid code with invisible Unicode characters. In March 2026, several research teams reported a new wave:
- StepSecurity named the GitHub part of the wave "ForceMemo". Starting on 8 March 2026, attackers used compromised accounts to rebase the latest commit on a repository's default branch, append obfuscated code, and force-push the result. They kept the original commit message, author and author date. StepSecurity estimated more than 240 Python repositories in this wave.
- Aikido found more than 151 GitHub repositories carrying payloads hidden with invisible Unicode characters.
- Socket flagged 72 malicious or "sleeper" extensions on OpenVSX, some published clean and turned malicious in a later update.
- Two React Native npm packages,
react-native-international-phone-number0.11.8 andreact-native-country-select0.3.91, shipped malicious versions on 16 March.
The OpenSourceMalware community counted more than 433 affected components in total. BleepingComputer broke that down as 200 Python repos, 151 JS/TS repos, 72 extensions and 10 npm packages. All of these waves pull instructions from the same Solana address, which is why researchers attribute them to one operator.
Who is affected
- Developers who cloned, installed with
pip install git+https://…, or vendored code from an affected repository after 8 March 2026. Commonly targeted files includemain.py,setup.py,app.py,manage.pyandrun.py. - Users of OpenVSX-based editors (VSCodium, Cursor, Windsurf and others) who installed the flagged extensions.
- Projects that depend on the two React Native packages at the versions listed above.
- Anyone whose machine ran the payload. The infostealer goes after GitHub tokens (from
~/.git-credentials, the git credential store, VS Code extension storage andGITHUB_TOKEN), SSH keys, cloud credentials and crypto wallets.
What it means for developers and engineering teams
Three techniques make this campaign hard to catch.
Rewritten history that looks legitimate. A force-push that keeps the original author and message looks like an old, trusted commit in most UIs. The giveaway is the committer date, which is much newer than the author date, and StepSecurity often saw a committer email of null.
Code reviewers can't see. Invisible Unicode characters (zero-width and variation-selector code points) can encode a payload that displays as blank space in editors and diff views, and then gets decoded and passed to eval. The Python loader in ForceMemo used base64, zlib and an XOR key of 134, stored in a variable named lzcdrtfxyqiplpd.
C2 that's hard to take down. The loader reads the memo field of transactions on a Solana address, falling back across nine public RPC endpoints, to get the current payload URL. Blockchain records can't be seized like a domain, and the operator only needs to post a new transaction to rotate infrastructure. The payload then downloads Node.js v22.9.0 into the home directory, fetches an AES-encrypted JavaScript stage, writes i.js, and persists through ~/init.json. It exits if the system locale or timezone looks Russian.
The lesson is that a long-lived GitHub token on a laptop is effectively write access to every repo that person maintains. Once that token is stolen, the damage spreads to everyone downstream.
What to do now
- Look for the indicators in cloned code and on developer machines:
grep -rn "lzcdrtfxyqiplpd" ~/src ls -la ~/init.json ~/node-v22* 2>/dev/null find ~/src -name i.js -newer ~/.bashrc - Find rewritten commits:
git log --format='%h %ad %cd %ce %s' --date=iso -n 20. Investigate any commit where the committer date is days or months newer than the author date, or where the committer email isnull. - Protect default branches: turn on branch protection or rulesets that block force-pushes and require signed commits, so a stolen token can't silently rewrite
main. - Replace long-lived tokens with fine-grained, short-expiry PATs or the GitHub CLI's OAuth device flow, and rotate every token, SSH key and cloud key on a machine that ran the payload.
- Pin dependencies to commit SHAs or lockfile hashes instead of branch names when you install from Git.
- Restrict editor extensions to an allowlist, and turn off auto-update for extensions in sensitive environments. Sleeper extensions rely on updates.
- Scan for invisible Unicode in CI. For example, fail the build on code points in the U+FE00–U+FE0F and U+E0100–U+E01EF ranges or on zero-width characters in source files.
Related on TechLogHub
Sources
- StepSecurity: ForceMemo, hundreds of GitHub Python repos compromised via account takeover and force-push
- Aikido: GlassWorm strikes React packages
- Socket: GlassWorm sleeper extensions activated on Open VSX
- OpenSourceMalware: Four Arms, One Monster
- BleepingComputer: GlassWorm malware hits 400+ code repos (17 Mar 2026)
- The Hacker News: GlassWorm attack uses stolen GitHub tokens


