Threat actors are finding new ways to insert invisible code or links into open source code to evade detection of software supply chain attacks.

The latest example was found by researchers at Israel-based Koi Security, who this week said they have discovered a threat actor’s campaign that has been running since August, contaminating 126 packages in Microsoft’s npm open source code repository. There have been more than a combined 86,000 installs of these infected packages, and the campaign is continuing.

What’s the trick? The bad packages don’t contain malicious code that could be detected by a scanner. Instead, there’s an invisible link to a URL that, when the package is installed by a developer, fetches malicious code from the attacker’s server.

The invisible dependency could be hidden behind a line that simply says ‘Hello.’

“When you install a package with this kind of dependency, npm fetches it from that external URL,” the researchers note. “Not from npmjs.com, from wherever the attacker wants. And npmjs.com doesn’t follow those URLs. Security scanners don’t fetch them. Dependency analysis tools ignore them. To every automated security system, these packages show “0 Dependencies.” So, to the developer who downloaded an infected package from npm, the package looks safe.

Why does it work?

This works, say the researchers, because npm supports HTTP URLs as dependency specifiers, so when the malicious package is installed, npm automatically fetches it from the external URL.

The goal: To steal developer GitHub, GitLab, Jenkins and other credentials, and to obtain an outline of the developer’s environment – including public IP addresses, server hostnames, usernames, current directories and node.js version – for further exploitation. The data is then carefully exfiltrated.

Campaign also exploits AI

The names of packages uploaded to npm aren’t typosquats of common packages, a popular tactic of threat actors. Instead the hackers exploit AI hallucinations. When developers ask AI assistants for package recommendations, the chatbots sometimes suggest plausible-sounding names that are close to those of legitimate packages, but that don’t actually exist. These are the names the threat actor uses. So if a developer asks an AI assistant about a package called ‘eslint-plugin-unused-imports’ the chatbot might suggest the (unknowingly malicious) ‘unusued-imports’ package, and the developer might trust the recommendation and install that package.

Koi Security calls the tactic slopsquatting. They call the overall campaign PhantomRaven.

At some point, npm leadership either discovered this campaign on its own or was alerted by other researchers, because in August, 21 packages were removed from the repository. However, after September, 80 additional packages were uploaded. All, Koi Security believes, were clearly controlled by the same person.

‘Disastrous’ flaw in npm

This is a “disastrous” systemic design flaw in npm’s dependency management functionality, Tanya Janca, head of Canadian secure coding training firm She Hacks Purple Consulting, told CSO. The lack of validation for dependency URLs bypasses the trust boundary for the Node.js software supply chain, she said.

Few programming languages allow dependencies to be specified via URLs, and even most of those that do have package managers that block this feature due to security concerns, she said. For instance, she pointed out, it’s allowed in Python, but the open source Python Package Index repository of packages (PyPI) blocks this functionality.

The danger of the PhantomRaven attacks is that an threat actor can compromise developer and build systems, rather than end users directly, Janca said. “Because Node.js and npm are used by millions of projects, even a single compromised package can have cascading effects across that entire software ecosystem,” she said.

The attack is called an ‘unvalidated redirect’ [accepting an untrusted URL as data] and was on the Open Web Application Security Project’s (OWASP) Top Ten attacks as far back as in 2013, Janca said.

“Input validation is the number one most important step in all secure coding practices, and this feature of npm circumventing the developer’s ability to even be aware that this is happening is terrifying. This attack vector is likely to be use by many attackers in the near future until this is removed by npm.”

Microsoft was asked to comment on the Koi report and asked how it will better secure npm. A spokesperson said they were working on a reply but none had been received by publication deadline.

‘Invisible’ attacks

Threat actors have been using invisible code to fool defenders in many ways. For example, in August, a security blogger reported that Amazon’s Q Developer service could be fooled by invisible Unicode Tag characters. In another case, Unicode was used to hide malware in Visual Studio code extensions.

Oren Yomtov, author of the Koi Security report, said that Microsoft should enhance npm’s scanning tools to follow and analyze remote dependency URLs rather than ignoring them. Currently, security scanners don’t fetch HTTP URL dependencies, and dependency analysis tools ignore them, he said, making packages with remote dynamic dependencies appear to have “0 Dependencies.” Microsoft should also require security validation for any externally fetched dependencies.

Developers shouldn’t blindly trust AI tools for package recommendations, he added. As the report points out, when developers ask AI assistants like GitHub Copilot or IDEs like Cursor for package recommendations, the models sometimes suggest plausible-sounding package names that don’t actually exist. PhantomRaven took advantage of this, and created malicious versions of those non-existent packages. “Always verify packages exist on the official npm registry before installation,” he advised, “and audit package.json files for suspicious HTTP URL dependencies.”

In addition, CSOs should have endpoint visibility into all software types, not just traditional binaries. “PhantomRaven demonstrates how sophisticated attackers exploit blind spots in traditional security tooling, as remote dynamic dependencies aren’t visible to static analysis,” he said. “Implement governance controls across the entire software intake surface, including code packages, extensions, and AI models that traditional MDMs and EDRs miss.”

Read More