Malicious code in express-chai (npm)
express-chai, a malicious npm package impersonating the pino logger middleware, contained obfuscated code that fetches and executes arbitrary code from a remote server (https://gray-dyane-31.tiiny.site/index.json) at middleware initialization time, granting full Node.js process access to an attacker.
- Disclosed
- Last updated
- Blast radius
- Any Node.js application that installed and used express-chai as middleware
- Ecosystems
- Attack vectors
- Affected entities
- express-chainpm package impersonating pino logger middleware
express-chai was published to npm as a malicious package designed to impersonate the legitimate pino logging library. The package exported a middleware factory that, when invoked, executed obfuscated code in lib/caller.js.
The malicious code decoded a base64-encoded URL (https://gray-dyane-31.tiiny.site/index.json) and fetched a JSON payload via axios, using a base64-encoded dev-secret-key header for authentication. The response's cookie field was passed to new Function.constructor("require", s) and executed with access to the local require function.
This attack granted the attacker arbitrary code execution inside the installer's Node.js process at middleware setup time, with full access to require and the surrounding application context. The package used obfuscation and naming/keyword mimicry to disguise itself as a legitimate logging library.
The incident was identified and credited to the OpenSSF's malicious-packages repository.
Indicators of compromise
- Packages
- express-chai
- Domains
- gray-dyane-31.tiiny.site
Remediation
- Immediately uninstall express-chai from all projects
- Audit npm install logs to identify when express-chai was installed
- Rotate all credentials and secrets that may have been exposed to the compromised process
- Review application logs for suspicious activity during the period express-chai was active
- Scan systems for indicators of compromise from the attacker's remote server
- Use npm audit to check for other malicious packages
- Implement package verification and allowlisting policies for npm dependencies
Sources
- GitHub Advisory GHSA-539g-57mc-c49q · GitHub Advisory Database
Cite this entry
"Malicious code in express-chai (npm)." supplychainattack.org, Supply Chain Attack Incident Catalog. Disclosed August 7, 2026; last updated August 7, 2026. https://supplychainattack.org/incident/malicious-code-in-express-chai-npm-1bgsxw
Suggest a correction
Found an error or have a newer source? Corrections to factual errors take priority over new entries.
Related incidents
- resolvedcritical
Malicious code in github-policy-bot (npm)
The npm package github-policy-bot contained malicious code that exfiltrated host identifiers and environment metadata during installation via a postinstall script. The package name shadowed a legitimate Google-owned repository and was authored under a placeholder account claiming security research purposes.
npmCompromised packageTyposquatting - containedcritical
Malicious code in crypto-javas (npm)
The npm package crypto-javas contains malicious code in its postinstall hook and main entrypoint that harvests environment variables (including CI secrets like AWS_*, GITHUB_TOKEN, NPM_TOKEN) and exfiltrates them to an attacker-controlled backend. The package is presented deceptively as @wizlabs/js-crypto with a placeholder repository.
npmCompromised packageTyposquatting - resolvedcritical
Malicious code in react-dom-helpers (npm)
The npm package react-dom-helpers, a typosquat of the legitimate react-dom, contained malicious code that exfiltrated host identifiers (local IPv4 addresses, public IP, and system information) to a hardcoded Slack webhook on module load.
npmTyposquattingCompromised package - resolvedcritical
Malicious code in localize-extract (npm)
localize-extract@1.0.0 on npm contained malicious postinstall code that exfiltrated host identifiers to an attacker-controlled endpoint. The package name resembled @angular/localize, suggesting a dependency-confusion or typosquatting attack.
npmCompromised packageTyposquattingDependency confusion