đ¨ node-ipc is compromised again.
Three new malicious versions just dropped: 9.1.6, 9.2.3, and 12.0.1. Socketâs AI scanner flagged them as malware within three minutes of publication.
The attack vector: a dormant maintainer account (atiertant) was likely taken over via an expired email domain. The attacker registered the lapsed domain, triggered an npm password reset, and gained publish rights to a package with millions of historical downloads.
The payload is a credential stealer embedded in the CommonJS entrypoint (node-ipc.cjs). It activates on require(ânode-ipcâ), not through a postinstall script. Hereâs what it does:
â˘Fingerprints the host (OS, arch, hostname, uname)
â˘Harvests 113-127 credential file patterns depending on platform (AWS, GCP, Azure, SSH keys, Kubernetes configs, npm tokens, .env files, shell histories, macOS Keychain databases, and more)
â˘Dumps the entire process.env, capturing every CI secret and cloud credential in memory
â˘Builds a gzip archive in a temp directory
â˘Exfiltrates everything over DNS TXT queries to bt[.]node[.]js, using a bootstrap resolver at sh[.]azurestaticprovider[.]net:443 (a deliberate lookalike of Microsoftâs Azure Static Web Apps domain)
The DNS exfiltration is chunked. A 500 KB archive generates roughly 29,400 TXT queries. The body is XOR-encrypted with a SHA-256 keystream, base64-encoded, alphabet-substituted, and split into 31-character chunks before hex-encoding into DNS labels. Header, data, and footer queries use xh, xd, and xf prefixes respectively.
The malware forks a detached child process (env var __ntw=1) so credential theft runs silently in the background. It also exposes a __ntRun export, meaning any downstream code that calls require(ânode-ipcâ).__ntRun() can trigger a second collection/exfiltration cycle.
ESM-only consumers using the import path are not affected by the reviewed package metadata. CommonJS consumers are.
This is the same package involved in the 2022 protestware incident. It has a history.
If you use node-ipc:
â˘Do not install 9.1.6, 9.2.3, or 12.0.1
â˘Audit your lockfiles for these versions
â˘If you loaded the CommonJS entrypoint, treat all environment variables, SSH keys, cloud credentials, npm tokens, and local secrets as compromised. Rotate immediately.
â˘Hunt for DNS TXT queries to bt[.]node[.]js and sh[.]azurestaticprovider[.]net in your network logs
â˘Check for temp files matching
/nt-/.tar.gz
Credit to Ian Ahl (@TekDefense) for first publicly identifying the expired-domain account takeover vector.
Developing story. Full technical breakdown and IOCs on the Socket blog: