A sophisticated threat actor known as GlassWorm has escalated its supply chain attack campaign in a major new operation that researchers at StepSecurity are tracking as ForceMemo. Having spent months compromising VS Code extensions to steal developer credentials, GlassWorm has now pivoted to using those stolen GitHub tokens to directly inject malware into hundreds of Python repositories on GitHub — silently rewriting git history in a way that leaves almost no visible trace in GitHub's interface. The campaign has been active since March 8, 2026 and is still ongoing. As of March 13, over 240 Python repositories have been confirmed compromised, with the malware targeting Django apps, ML research code, PyPI packages, and Streamlit dashboards. Any developer who ran pip install or cloned and executed code from a compromised repository during this window may have triggered the payload.
Affected products
- ·Python repositories on GitHub containing setup.py, main.py, or app.py — 240+ confirmed compromised as of March 13, 2026
- ·VS Code extensions on the Open VSX marketplace — 151+ repositories compromised March 3–9, 2026
- ·Cursor editor extensions — confirmed infection vector for GitHub credential theft
- ·Two React Native npm packages: react-native-international-phone-number and react-native-country-select (npm user "astroonauta") — briefly compromised with malicious versions
- ·Any developer environment where GitHub tokens, ~/.git-credentials, or GITHUB_TOKEN environment variables are stored locally
How to Fix
Step-by-step remediation
The immediate priority is auditing your VS Code and Cursor extension list. GlassWorm specifically targeted the Open VSX marketplace, so any extension installed from there since October 2025 is suspect — particularly if you cannot verify the developer's identity independently. Remove any extension you do not recognise. Next, revoke every GitHub personal access token in your account immediately and generate fresh ones after you have cleaned your environment. Tokens stored in ~/.git-credentials or the GITHUB_TOKEN environment variable are specifically harvested by GlassWorm's credential theft module. For your repositories, run a git log check looking for commits where the author date and committer date diverge unexpectedly — this is the clearest programmatic fingerprint of a ForceMemo injection. Search your Python files for Base64-encoded payloads appended at the end of setup.py, main.py, or app.py — the injection always appends rather than inserting mid-file. If you published any PyPI package versions during the March 8–13 window, audit those releases and compare against your intended codebase — consider yanking any versions you cannot verify clean. If you find evidence of compromise, treat your entire local developer environment as potentially hostile and rotate all credentials stored in it including npm tokens, cloud provider keys, and any cryptocurrency wallet seeds accessible from that machine.
What happened
GlassWorm's attack chain is a multi-stage operation that began months before the GitHub injections. The threat actor first compromised VS Code and Cursor extensions on the Open VSX marketplace — starting in October 2025 with an attack that was downloaded over 35,000 times before being contained, followed by further waves in November 2025 and January 2026 affecting tens of thousands more developers. GlassWorm's stage 3 payload includes a dedicated credential theft module that harvests GitHub tokens from multiple sources on an infected developer's machine: the git credential store, VS Code extension storage, the ~/.git-credentials file, and the GITHUB_TOKEN environment variable. Those stolen credentials were then validated against the GitHub API and exfiltrated to attacker-controlled servers. The Solana C2 wallet address linked to the campaign shows its earliest transaction on November 27, 2025 — meaning the attacker was building infrastructure for over three months before launching the ForceMemo GitHub injection wave on March 8, 2026.
The ForceMemo injection technique is what makes this campaign technically notable. Once the attacker has a developer's GitHub token, they access the victim's repositories and rebase the latest legitimate commit on the default branch with malicious code appended to Python files — then force-push the changes. The original commit message, author name, and author date are all preserved exactly. Only the committer date changes — a subtle difference that most developers would never notice during a routine code review. This technique rewrites git history completely and leaves no pull request, no new commit in GitHub's web UI, and no diff notification. A Reddit user first noticed the attack when they discovered that "null" had committed to most of their repositories and traced the infection back to a compromised Cursor extension. The injected payload is a Base64-encoded blob appended to the end of standard Python entry point files — setup.py, main.py, or app.py. The payload first checks whether the system locale is set to Russian — if it is, execution is skipped entirely, a common indicator of a Russian-speaking threat actor avoiding domestic targeting. For all other systems, the malware queries the transaction memo field of a specific Solana wallet to retrieve the payload URL dynamically — a novel command-and-control technique that makes the C2 infrastructure extremely difficult to block because the attacker can update the payload URL multiple times per day simply by making a new Solana transaction.
Real-World Impact
The downstream payload delivered by GlassWorm is encrypted JavaScript designed to steal cryptocurrency and sensitive data from the infected developer's machine. The implications extend beyond the individual developer. When a Python package on PyPI is compromised, every user who installs that package becomes a downstream victim — without any indication that anything is wrong, because the package looks legitimate, the repository commit history looks intact, and the publisher's identity is genuine. The same logic applies to Django applications deployed in production, ML research code shared between teams, and Streamlit dashboards used inside organisations. Aikido Security confirmed that 151+ GitHub repositories were compromised in the first GlassWorm wave between March 3–9 using invisible Unicode characters to hide payloads — a parallel campaign from the same actor using different obfuscation but the same Solana C2 infrastructure. The two waves combined — 240+ repositories from ForceMemo and 151+ from the Unicode steganography wave — represent one of the broadest GitHub supply chain compromises documented in 2026.
Technical Details
🛡️ Prevention Tips
This attack is a direct consequence of VS Code extension trust. Most developers install extensions without auditing the publisher, reviewing the source code, or monitoring for silent auto-updates. GlassWorm exploited that blind trust for months across multiple waves before pivoting to GitHub account takeover. The practical prevention measures are straightforward but require discipline: audit your installed extensions periodically, prefer extensions from the official VS Code Marketplace over Open VSX where possible, store GitHub tokens with minimal scope and short expiry windows rather than broad long-lived tokens, use environment-specific tokens that expire automatically, and consider enabling GitHub's push protection and branch protection rules to prevent force-pushes to default branches on your repositories. Branch protection that requires pull request review before merging would have blocked the ForceMemo injection technique entirely on protected repositories.
FAQs
How do I know if I installed a compromised VS Code extension?
GlassWorm targeted extensions on the Open VSX marketplace across three waves — October 2025 (35,000+ downloads), November 2025 (10,000+ downloads), and January 2026 (22,000+ downloads). If you installed any VS Code or Cursor extensions from Open VSX during these periods without verifying the publisher independently, treat your GitHub tokens and npm credentials as potentially compromised and rotate them immediately.
How can the malware hide in my git history without me noticing?
ForceMemo uses force-push to rebase commits — it completely rewrites the git history on the default branch, preserving the original commit message, author name, and author date. The only detectable difference is that the committer date changes. GitHub's web UI does not prominently display the committer date, so the injected commit looks identical to the original legitimate commit. Running git log --format="%an %ae %ad %cd" on your repository will reveal discrepancies between author date and committer date where a ForceMemo injection occurred.
Read Next
chrome · zero day
Google Patches Two Chrome Zero-Days Actively Exploited in the Wild — Skia and V8 Engine Both Affected
axios · npm
North Korea's UNC1069 Backdoored Axios npm Package — 183 Million Weekly Downloads Exposed to WAVESHAPER.V2 Backdoor
supply chain · npm
From a Stolen Token to Full AWS Admin Access in 72 Hours — The UNC6426 nx Supply Chain Attack Explained
npm · strapi
36 Malicious npm Packages Disguised as Strapi Plugins Exploit Redis and PostgreSQL to Deploy Persistent Implants and Reverse Shells
weekly roundup · cybersecurity