⏱️ Reading time: 14 min
Kevin Beaumont, the researcher who tracked WannaCry and posts as @GossiTheDog, wrote on Mastodon that the Claude Code extension had allegedly been compromised. Anthropic has not confirmed the report, and the post offers no verifiable technical indicators.
📑 En este artículo
- TL;DR
- What Does It Mean to Audit Code Extensions?
- Why It Matters: From a Mastodon Report to a Confirmed Backdoor in LiteLLM
- How a Malicious Extension Works Under the Hood
- Getting Started: Auditing an Extension Step by Step
- What to Do If You’ve Already Installed a Suspicious Extension
- Real-World Cases: Beyond LiteLLM
- Common Mistakes and Best Practices
- Audit Tools Comparison
- Going Deeper: Provenance, SBOM, and Cryptographic Signatures
- Frequently Asked Questions
- How do you audit software dependencies without paying for commercial tools?
- Was Kevin Beaumont’s report about Claude Code confirmed?
- What’s the difference between a backdoor and excessive telemetry in an extension?
- Is it enough to review the source code on GitHub before installing a package?
- How often should you re-verify third-party packages?
- References
Whether this particular claim gets confirmed or not makes little difference: the same pattern, official code that ends up leaking credentials, explains why more and more teams treat every extension, plugin, or package as untrusted code until proven otherwise. And that pattern already has a confirmed case this year: LiteLLM 1.107.0 on PyPI.
TL;DR
- Reviewing permissions, network calls, and dependencies before installing catches backdoors like the one in LiteLLM 1.107.0 on PyPI.
- A postinstall script in npm or an import hook in pip can exfiltrate credentials without showing a single error.
- npm’s –ignore-scripts flag and pip-audit detect or block unreviewed installation code.
- osv-scanner checks your lockfile against the public OSV.dev database before the attack reaches production.
- An extension marked as official doesn’t guarantee the absence of hidden telemetry or compromised dependencies.
What Does It Mean to Audit Code Extensions?
Auditing code extensions is the process of reviewing a plugin’s or package’s permissions, network calls, and dependencies before installing it, even if it comes from an official marketplace. The goal is to catch credential theft, hidden telemetry, or injected code before it runs on your machine or in a CI/CD pipeline.
The word “official” creates a false sense of security. An extension marketplace, a package registry like npm or PyPI, or an open source project’s verified account certify the identity of the publisher, not the absence of malicious code in every version. Auditing fills exactly that gap: the distance between “it was published by who they say they are” and “the code they published is safe”.
Why It Matters: From a Mastodon Report to a Confirmed Backdoor in LiteLLM
Beaumont’s post includes no hashes and no public technical analysis. It’s the claim of a well-known researcher, not a published audit or a confirmation from Anthropic. Treating it as an established fact would repeat the exact mistake every security guide warns against: accepting a source without corroborating it.
The real risk doesn’t depend on whether this particular report gets confirmed. There’s already a documented case with the same pattern: LiteLLM, the open source proxy for unifying language model APIs, published version 1.107.0 on PyPI with a credential stealer and a backdoor built into the package. Anyone who installed that version with a simple pip install litellm==1.107.0 ran that code with the same permissions as their own application.
The lesson isn’t “don’t use LiteLLM” or “don’t trust Anthropic”: it’s that no platform (PyPI, npm, an extension marketplace) reviews every release line by line before distributing it. Quality control, in practice, falls on whoever installs the package.
How a Malicious Extension Works Under the Hood
Most attacks through this channel don’t exploit a memory vulnerability or a sophisticated exploit. They abuse a legitimate mechanism that nearly every package manager offers: running code automatically during installation.
Automatic Installation Scripts
In npm, the scripts.postinstall field in a package.json runs as soon as the package finishes downloading, without the user explicitly approving it. In pip, the classic equivalent is a setup.py with module-level code, outside any function, that Python executes during the build. Both mechanisms exist for legitimate reasons, like compiling a native dependency, but they’re indistinguishable at a glance from a script that exfiltrates environment variables.
Undeclared Telemetry
An editor extension (VS Code, JetBrains) can declare broad permissions, like file or network access, which the marketplace approves because they’re part of the editor’s own business model. Nothing prevents the extension from also sending events to its own analytics domain, beyond its advertised function, without breaking any formal marketplace rule.
Compromised Transitive Dependencies
The package you deliberately install is almost never the problem. The problem is usually two or three levels down, in a dependency of a dependency that no one on your team has ever reviewed. An npm ls --all on a mid-sized project easily returns several hundred transitive packages.
Broad Permissions in Code Assistant Extensions
AI coding assistant extensions, like Claude Code, GitHub Copilot, or Cursor, are a special case because their very function requires broad access: reading the entire repository, running shell commands, and, in many workflows, reading environment variables where API tokens and cloud credentials typically live. That level of access isn’t a design flaw, it’s necessary for the tool to work, but it turns any extension of this kind into a high-value target: compromising it once grants access to everything the developer could touch.
sequenceDiagram
participant Dev as Developer
participant Reg as Package registry
participant Script as Install script
participant C2 as Attacker server
Dev->>Reg: pip install litellm 1.107.0
Reg-->>Dev: delivers the package
Dev->>Script: runs installation
Script->>C2: sends environment variables
Note over Dev,C2: exfiltration happens before the package is first used
⚠️ Heads up: npm’s --ignore-scripts flag blocks the installation scripts of ALL dependencies, not just the suspicious ones. It can break legitimate packages that compile native binaries during install.
Getting Started: Auditing an Extension Step by Step
This checklist assumes you already have Node.js and npm installed, any recent version of Node includes npm. If you work in Python, the equivalent commands use pip and are noted in parentheses.
Checklist for Auditing Code Extensions Before Installing
Before running npm install or adding an extension from a marketplace, four steps cut out most of the risk:
- Read the manifest without installing.
npm view express scripts --jsonshows the declared scripts without downloading or running anything. Expected output for a package with no install scripts:{}. If apostinstallorpreinstallkey shows up, review that script before moving on. - Review the dependency tree.
npm ls --all(orpip show -f <package>in Python) lists every transitive dependency. A small package with hundreds of lines of dependencies is a sign that auditing it by hand isn’t feasible, and you should lean on an automated tool instead. - Scan against known vulnerabilities. Google’s osv-scanner checks your
package-lock.jsonorrequirements.txtagainst the public OSV.dev database:osv-scanner scan source --lockfile=package-lock.json. If there are no matches, the command finishes without listing any vulnerabilities and returns exit code 0. - Watch network traffic in an isolated install. Run the installation inside a disposable container or VM and capture outgoing connections with
strace -f -e trace=network -o output.log npm install. A package that only contactsregistry.npmjs.orgis expected; a connection to an unknown domain in that log is the red flag that justifies not going further.
For Editor Extensions (VS Code, JetBrains)
The same principle applies to editor extensions, with one practical difference: most don’t expose a manifest as readable as package.json. code --list-extensions --show-versions lists what you already have installed; before adding a new one, checking its marketplace page for declared permissions and, above all, for who publishes it (the project’s own account versus a third-party fork) avoids most impersonation cases.
flowchart TD
A["New extension to install"] --> B{"Verified publisher?"}
B -->|"No"| X["Reject"]
B -->|"Yes"| C{"Declared install scripts?"}
C -->|"Yes"| D["Review the script line by line"]
C -->|"No"| E{"Excessive transitive dependencies?"}
D --> E
E -->|"Yes"| F["Scan with osv-scanner"]
E -->|"No"| G["Install and monitor network traffic"]
F --> G
What to Do If You’ve Already Installed a Suspicious Extension
If the audit comes too late and the extension is already installed and in use, the order of the actions matters more than the speed of each one.
- Rotate credentials first, investigate later. Any API token, cloud key, or password accessible from the environment where the extension ran should be considered compromised. Rotating them doesn’t wait for confirmation of actual exfiltration.
- Check outbound network logs. If you have an egress firewall or a corporate proxy, look for connections to domains that don’t match the package’s official registries (registry.npmjs.org, pypi.org, the project’s own domain) during the window the extension was active.
- Check for persistence. A backdoor that only steals credentials once is serious but contained; one that installs a scheduled task, a git hook, or a service that survives uninstallation is an incident of a different scale. Checking
crontab -l, hooks in.git/hooks/, and new system services covers the most common persistence vectors. - Document the full chain. Exact version installed, date, and which credentials were accessible at that moment. That’s the information any later report to the security team or the affected project itself will need.
flowchart LR
A["Suspicious extension detected"] --> B["Rotate credentials"]
B --> C["Review network logs"]
C --> D["Check for persistence"]
D --> E["Document the incident"]
📌 Note: an AI coding extension typically requests read and write access to the entire repository and to the environment variables of the shell it runs in. That level of access is exactly what makes this attack vector attractive.
Real-World Cases: Beyond LiteLLM
The pattern isn’t exclusive to one ecosystem. In 2026, researchers documented a campaign attributed to North Korean actors that infected more than 1,700 packages distributed across npm, PyPI, Go, and Rust with malware, exploiting the same mechanism: an installation script or an import hook that runs without human review. The scale changes, the vector stays the same.
The Claude Code case Beaumont reports, confirmed or not, fits that same risk category: an extension with direct access to the development environment (environment variables, API tokens, project files) is a high-value target precisely because it runs with the same permissions as the developer who installed it.
For teams in Latin America integrating AI agents into their workflow on repositories with customer data, the cost of a leaked credential isn’t just technical: it can trigger a mandatory user notification under local data protection law. In that context, auditing beforehand is as much a matter of compliance as it is of security.
Common Mistakes and Best Practices
- Trusting the “verified” badge without reviewing the content. A marketplace certifies the publisher’s identity, not the absence of malicious code in every update.
- Not pinning exact versions. A range like
^1.107.0instead of an exact1.107.0in the lockfile lets a compromised update install itself on the nextnpm install. - Ignoring install scripts out of habit. Most developers have never read a
postinstallscript of a dependency they use every day. - Not monitoring outbound traffic. Without a record of which domains a tool contacts, a credential exfiltration can go undetected for months.
- Auditing once and forgetting about it. An extension that’s clean today can receive a compromised update next week; auditing is an ongoing process, not a one-time task.
Audit Tools Comparison
| Tool | What it detects | When to use it | Limitation |
|---|---|---|---|
| npm audit | Known vulnerabilities in Node.js dependencies | Before every release, integrated into CI | Only covers the npm ecosystem and already-reported vulnerabilities |
| pip-audit | Known vulnerabilities in Python packages | In the CI pipeline of Python projects | Doesn’t analyze runtime behavior |
| osv-scanner | Checks lockfiles against the multi-ecosystem OSV.dev database | Periodic audits in repos with multiple languages | Depends on the vulnerability already being reported in OSV |
| Network sandbox (strace, mitmproxy) | Undocumented outbound connections during installation | Before approving a new dependency, one time | Requires setting up isolation manually, not automatic |
Going Deeper: Provenance, SBOM, and Cryptographic Signatures
For teams managing hundreds of dependencies, reviewing manifests by hand doesn’t scale. The industry is converging on several complementary mechanisms.
Software Bill of Materials (SBOM)
An SBOM is a formal inventory, in SPDX or CycloneDX format, of every component that makes up a software artifact, with its exact version and license. Tools like syft generate an SBOM from a container image or a repository, which lets you answer “do we use the compromised version of this package anywhere?” in seconds instead of checking project by project.
Verifiable Provenance with SLSA
The SLSA (Supply-chain Levels for Software Artifacts) framework defines levels of assurance about how an artifact was built, from “the build ran somewhere” to “the build ran on an isolated system, with the source code and build steps cryptographically signed and verifiable by a third party”. A package with a high SLSA provenance level reduces, though doesn’t eliminate, the chance that someone inserted code between the repository and the distribution registry.
Signing with Sigstore
Sigstore lets you sign an artifact without managing a permanent private key: it uses short-lived certificates tied to an identity, like a GitHub account, and records the signature in a public, immutable log. Verifying that signature against an image confirms that chain. Without this, confirming that a published binary matches the public source code exactly depends on the maintainer’s good faith.
Reproducible Builds
A reproducible build lets anyone, compiling the same source code with the same tools, get exactly the same binary, byte for byte, as the one the maintainer published. If two independent parties reproduce the same result, the chance that the published binary contains something not in the public source code drops drastically. Debian and the Tor project are two of the oldest examples of this approach applied in production.
Your next step: run npm view <package> scripts --json on a dependency you already use every day and confirm it doesn’t declare any postinstall script you haven’t reviewed before.
Frequently Asked Questions
How do you audit software dependencies without paying for commercial tools?
Free tools cover most cases: npm audit and pip-audit are free, osv-scanner is open source, and reviewing manifests with npm view costs nothing. The value of commercial tools like Socket.dev or Snyk lies in automated continuous monitoring, not in basic detection capability.
Was Kevin Beaumont’s report about Claude Code confirmed?
No, as of this writing Anthropic has not published either a confirmation or a public denial of the Mastodon post. Treat it as an alert worth following, not as an established fact.
What’s the difference between a backdoor and excessive telemetry in an extension?
A backdoor runs code with the explicit intent of granting unauthorized access or stealing data, as in the LiteLLM case. Excessive telemetry is usually disclosed somewhere in the terms of use, even if barely visible; it’s still a privacy problem, but it isn’t, technically, an attack.
Is it enough to review the source code on GitHub before installing a package?
Not always. The code published in the registry (npm, PyPI) doesn’t always match the public repository; without verifiable provenance, like SLSA or Sigstore, there’s no automatic guarantee that both are identical. That’s why it’s better to audit the package that actually gets installed, not just the repository.
How often should you re-verify third-party packages?
At minimum, on every major or minor version update of a critical dependency, and automatically, with osv-scanner or a similar tool, on every CI build. A one-time review loses value the moment the next update appears.
References
- Mastodon (@GossiTheDog): Kevin Beaumont’s post reporting, without public confirmation, the alleged compromise of the Claude Code extension.
- LiteLLM repository on GitHub: the open source project affected by the compromised package published on PyPI.
- osv-scanner: Google’s scanner that checks lockfiles against the public OSV.dev vulnerability database.
- Official npm documentation on scripts: reference for how and when install scripts like postinstall run.
- SLSA (Supply-chain Levels for Software Artifacts): a framework of verifiable provenance levels for software artifacts.
📱 Enjoying this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day.
Featured image: Foto de Lewis Kang’ethe Ngugi en Unsplash
Did it work for you? Got a different error? Say so below: questions get answered and help the next reader.
Leave a comment
0 Comments