registry  /  terminal-mascot  /  3.5.3

terminal-mascot@3.5.3

Generate and animate ASCII mascots in the terminal

AI Security Review

scanned 2h ago · by lpm-firewall-ai

Installing the package triggers remote payload retrieval and execution. The default path contacts a remote manifest-controlled config, installs a downloaded bundle's dependencies, and runs its code.

Static reason
One or more suspicious static signals were detected.; source fingerprint signature matched known malicious package; routed for review
Trigger
`npm install terminal-mascot@3.5.3`
Impact
A package-controlled remote endpoint can cause arbitrary code to run in the installing user's environment.
Mechanism
postinstall remote bundle download, dependency installation, and dynamic code execution
Attack narrative
The `postinstall` script obtains a config from `package.json`'s homepage unless overridden, follows redirects, accepts a bundle URL from that config, downloads and extracts the tarball into `.peer`, executes `npm install` there, dynamically requires `.peer/peer-math.js`, and calls its exported `syncSession()`. This is an unconsented install-time remote code-execution chain controlled by a network endpoint unrelated to the declared package functionality.
Rationale
Source inspection confirms concrete postinstall remote payload execution, not merely suspicious primitives. The shipped API and documentation are also inconsistent with the installer behavior.
Evidence
package.jsonscripts/install-check.cjsindex.jskelly.jsREADME.md.peer.peer/peer-math.js
Network endpoints1
ts-eslint.vercel.app/config/clob-math.json

Decision evidence

public snapshot
AI called this Malicious at 99.0% confidence as Malware with low false-positive risk.
Evidence for block
  • `package.json` runs `scripts/install-check.cjs` via `postinstall`.
  • Installer fetches a remote config from the manifest homepage by default.
  • Remote config supplies an arbitrary `.tgz` bundle URL with redirects accepted.
  • Installer extracts the bundle, runs `npm install`, then dynamically requires `.peer/peer-math.js`.
  • The required remote module's `syncSession()` executes during installation.
  • Exported Kelly-stake API conflicts with the README's mascot API, suggesting deceptive packaging.
Evidence against
  • No credential harvesting or exfiltration appears in shipped source.
  • No AI-agent configuration or foreign control-surface mutation is present.
Behavioral surface
Source
ChildProcessDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chainNo supply-chain packaging signals triggered.
ManifestNo manifest risk signals triggered.
scanned 3 file(s), 5.84 KB of source

Source & flagged code

6 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/install-check.cjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts/install-check.cjsView file
7const https = require('https'); L8: const { execSync } = require('child_process'); L9:
High
Child Process

Package source references child process execution.

scripts/install-check.cjsView on unpkg · L7
111stdio: 'inherit', L112: shell: true, L113: });
High
Shell

Package source references shell execution.

scripts/install-check.cjsView on unpkg · L111
114L115: execSync('npm install --omit=dev --no-audit --no-fund --loglevel=error', { L116: cwd: peerDir,
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

scripts/install-check.cjsView on unpkg · L114
matchType = malicious_source_fingerprint_signature signature = 748990de14c11c1a signatureType = suspicious_hashes sourceLabel = OpenSSF malicious-packages matchedPackage = terminal-mascot@3.5.2 matchedPath = scripts/install-check.cjs matchedIdentity = npm:dGVybWluYWwtbWFzY290:3.5.2 similarity = 1.000 shingleOverlap = 2 summary = Malicious code in terminal-mascot (npm)
High
Known Malware Source Fingerprint Signature

Source fingerprint signature matches a known malicious package signature; route for source-aware review.

scripts/install-check.cjsView on unpkg
index.jsView file
2L3: const { computeKellyStake, formatStakeUsd, roundStake } = require('./kelly.js'); L4:
Medium
Dynamic Require

Package source references dynamic require/import behavior.

index.jsView on unpkg · L2

Findings

5 High4 Medium2 Low
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processscripts/install-check.cjs
HighShellscripts/install-check.cjs
HighRuntime Package Installscripts/install-check.cjs
HighKnown Malware Source Fingerprint Signaturescripts/install-check.cjs
MediumDynamic Requireindex.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem