Bug bounty hunter planted an AI-written stealer on npm

Published

Two packages sat on npm doing almost nothing. transform-jsbi-to-bigint and sort-imports-es6-autofix carried a few lines of harmless JavaScript, close enough to real developer tools that a typo would land you on them. The working part was one line in the manifest. Instead of naming another npm package as a dependency, they pointed at a plain web address on a server the author controlled, and installing one sent npm off to fetch whatever was waiting there.

What was waiting there was an information stealer. CrowdStrike says the person who put it there was a bug bounty hunter.

In research published on 15 September, CrowdStrike Counter Adversary Operations analyst Maddie Stewart set out how the company traced the JavaScript stealer it calls PhantomRaven to a financially motivated actor who works the public disclosure circuit. The malware scrapes credentials and build system settings off developer machines. CrowdStrike assesses that the operator used what it found not to sell logs, but to write up bug reports and collect the rewards. CrowdStrike published the full analysis here.

The bounty is the business model

Most criminal tooling ends up in a market. Stolen logs get sold by the crate to whoever wants them, which is usually how researchers find out a stealer exists at all. CrowdStrike says it hasn't seen PhantomRaven logs offered on any log shop, and that absence is the detail that pushes this story somewhere new. The company reads it as evidence the operator kept the tool to themselves and pointed it purely at finding bug bounty opportunities.

The trail starts with an email. In November 2025 the actor contacted an organization to report that one of its devices was compromised, and blamed the compromise on a dependency confusion attack using malicious npm packages, which is the same technique that delivers PhantomRaven. The username on that email contained the string JPD. CrowdStrike then found two npm accounts, jpdhellonpm1 and jpd15, both publishing PhantomRaven packages and both carrying the actor's name and initials in the package description and author fields. Related usernames logged by other researchers include jpd12, jpd13, npmhell, npmpackagejpd and jpdhackerone11. That last one names a disclosure platform outright.

On their public X profile the actor describes themselves as a bug bounty hunter, active since November 2022, with bounties collected from at least nine organizations across technology, retail and hospitality through Bugcrowd, Intigriti, YesWeHack, HackenProof and HackerOne. In August 2025 they claimed publicly to have found a remote code execution flaw by publishing a malicious npm package and running their own preinstall script on the target's machine. CrowdStrike couldn't verify that claim, but notes the November 2025 campaign used much the same technique. Dependency confusion has been run at scale before, including a campaign that flooded npm with 993 fake packages aimed at a single bank.

There's an earlier mark on the record. In February 2025 the actor opened a GitHub issue asking why their code wouldn't upload to PyPI. A member of the PyPI organization explained the naming policy that exists to stop exactly this kind of attack, then accused them of trying to build an information stealer and linked the project as evidence. The project was pulled. Several of the Python files remain reachable, and CrowdStrike says they hold stealer code much like PhantomRaven, written for PyPI rather than npm. Somebody said this out loud nine months before the incidents.

A package that fetches its own malware

The delivery trick matters because it defeats the obvious defence. A typosquatted package that ships malware in its own files can be scanned, by the registry and by anyone auditing it. These packages shipped a Hello, world! script and nothing else. The dependency they declared was an HTTP address rather than a package name, what CrowdStrike calls a remote dynamic dependency, so the payload never sat in the registry at all. npm pulled it from the attacker's infrastructure at install time, and the fetched package carried a preinstall script, which runs automatically as part of installation rather than waiting for anyone to call the code.

That last part has since changed. CrowdStrike notes that npm shipped a version of its package manager in June 2026 that blocks preinstall scripts in dependency packages unless the developer explicitly allows them. On npm 12 and later an install prints a warning naming the blocked script, and the developer has to run an approval command after looking at what it does.

What it takes off a build server

PhantomRaven itself isn't clever, and CrowdStrike doesn't pretend otherwise: it describes the author's technical sophistication as likely low. What the malware is, is well aimed. Alongside routine system details (operating system, architecture, hostname, local and external IP address, Node version, working directory and process ID) it pulls usernames and email addresses out of Git and npm configuration files, then goes after continuous integration environment variables for GitHub Actions, GitLab CI, Jenkins and CircleCI, likely in an attempt to collect account credentials.

That list is the whole point. Variables such as GITHUB_ACTOR, CI_PROJECT_PATH, JENKINS_URL and npm_config_registry describe a build pipeline and who's allowed to touch it. A developer's laptop is one machine. A build agent is a key to everything that pipeline is trusted to publish, which is how a stealer aimed at one engineer becomes a supply chain problem for everybody downstream.

To learn the machine's public address the malware calls api64[.]ipify[.]org, an ordinary address lookup service with no connection to the attacker, then sends everything out over HTTP twice over: as a query string on a GET request, and as JSON in a POST body. Doing both is redundant. So is the user agent it puts on the POST, which is technically valid but stripped of the browser and version fields a real one carries.

The code tells on itself

CrowdStrike assesses with high confidence that the code was generated by a large language model, based on statistical token analysis together with two things any reader can see for themselves.

The first is the commenting. Every global variable and every function definition carries an explanatory comment directly above it, including where the comment tells you nothing the name below it didn't. A line reading "Convert system info to query string" sits over a function called buildQueryParams; "Send Data (GET and POST)" sits over one called sendData. Nobody writing for themselves annotates at that density.

The second is what never got finished. The stealer carries a fallback that exfiltrates over WebSocket if the HTTP requests fail, and the address hardcoded into it is wss[:]//yourserver[.]com/socket. That's placeholder text from a template. It was never replaced, and CrowdStrike judges it isn't real infrastructure.

Here's what that does and doesn't establish. Generated code carries no watermark, and a statistical assessment is an assessment, which is why CrowdStrike frames it as high confidence rather than as fact. What the evidence supports is narrower and more useful: somebody produced working, well targeted malware without the craft that normally comes with it, left the scaffolding in place, and shipped it anyway. CrowdStrike expects more of this, at moderate confidence, and points to AI generated PowerShell scripts deployed through late 2025 and early 2026 by ransomware operators it tracks as PUNK SPIDER and a TRAVELING SPIDER INC affiliate.

Turn install scripts off, or approve them one at a time

CrowdStrike's recommendations start with the install scripts, because that's the step that turns a download into an execution. Configure npm to use --ignore-scripts by default and enable script execution only for packages you trust. Update npm to the latest version so preinstall and postinstall scripts are restricted by default. Where you can, put a private registry in front of the public one so installs can be controlled, blocked and monitored rather than simply happening. Run npm audit for known problems, and make sure developers understand how dependency confusion abuses npm's own resolution rules, because the packages that carry this are built to look like a typo, not like malware.

Indicators

Defanged, from CrowdStrike's report. Command and control domains: npm[.]jpartifacts[.]com, packages[.]storeartifact[.]com, registry[.]storageartifact[.]com. Address: 54[.]173[.]15[.]59. Malicious packages: transform-jsbi-to-bigint and sort-imports-es6-autofix, published by npm users jpdhellonpm1 and jpd15.

Bug bounty programs run on an assumption that's held for two decades: the person reporting the flaw found it from the outside, and paying them is cheaper than letting somebody worse find it first. The operator CrowdStrike describes didn't wait to find anything. They shipped the access themselves, then invoiced for the discovery. Disclosure platforms were already absorbing a flood of AI written reports they have to triage by hand. A submission that's real, reproducible and manufactured is a harder problem than a fake one.

This briefing is provided by IntelFusions for informational and defensive purposes only. It is based on sources assessed to be reliable at the time of writing, and analytic judgments carry the confidence levels indicated. Indicators of compromise are defanged; re-arm them only in controlled environments. IntelFusions is not affiliated with the organizations named and makes no warranty as to completeness or accuracy.

Read the full analysis on IntelFusions