OpenSSF/OSV advisory MAL-2026-5904 confirms this npm version as malicious. Package name `chai-plugin` impersonates the popular `chai` assertion library — README and copyright headers reference chaijs.com / chaijs/chai, but the homepage is the lookalike `chaiplugin.com` and the author is unrelated to chai's real maintainer. Two obfuscator.io payloads (hex-named identifiers, rotated string array with a base64+URI custom decoder, control-flow obfuscation, arithmetic self-check) are glued onto...
Source
OpenSSF Malicious Packages via OSV
Summary
Malicious code in chai-plugin (npm)
Details
Package name `chai-plugin` impersonates the popular `chai` assertion library — README and copyright headers reference chaijs.com / chaijs/chai, but the homepage is the lookalike `chaiplugin.com` and the author is unrelated to chai's real maintainer. Two obfuscator.io payloads (hex-named identifiers, rotated string array with a base64+URI custom decoder, control-flow obfuscation, arithmetic self-check) are glued onto otherwise-legitimate chai source. (1) `lib/chai/utils/assertion.js` builds a URL with a query parameter, calls `require('http'|'https').get(url,...)`, accumulates the response body, then executes the bytes via `new Function('require', body)(require)` — an import-time dropper that runs whatever JS the remote server currently serves, with full Node `require` capability. (2) `lib/chai.js` destructures `spawn` from `child_process` and unconditionally invokes a top-level function that runs `spawn(<cmd>, [path.join(__dirname, <sibling>), JSON.stringify(opts)], {detached: true, stdio:...}).unref()`, backgrounding a malicious worker that survives the parent process. Both fire at module load via `index.js -> require('./lib/chai')`. The combination of typosquat name, obfuscation smuggled onto legitimate source, network-fetch-and-eval, and detached subprocess launch is a malicious supply-chain dropper.
Decision reason
OSV/OpenSSF confirms chai-plugin@4.5.2 as malicious package MAL-2026-5904. Malicious code in chai-plugin (npm)