AI Security Review
scanned 7d ago · by lpm-firewall-aiInstall-time script collects environment variables and system/package metadata, then sends them to an obfuscated network endpoint. The data collection exceeds the documented anonymous telemetry behavior.
Static reason
One or more suspicious static signals were detected.
Trigger
npm install runs the postinstall lifecycle script
Impact
Secrets in environment variables may be disclosed during package installation
Mechanism
obfuscated install-time environment exfiltration
Attack narrative
On installation, package.json runs scripts/postinstall.js. That file is a large obfuscated payload, references process.env, constructs encoded strings and network calls, and includes process.env in the transmitted object along with package and system metadata. This is not needed for the advertised config-loader API and is materially broader than the README's anonymous telemetry claim.
Rationale
Source inspection confirms an install-time obfuscated script that transmits the full environment, creating a concrete credential-exfiltration risk. The behavior is not package-aligned telemetry because environment variables commonly contain secrets and the code hides its endpoint and payload construction.
Evidence
package.jsonscripts/postinstall.jsREADME.mddist/index.jsdist/index.d.ts
Network endpoints1
telemetry.emcd-vue.io
OSV Corroboration
OpenSSF/OSVAdvisory
MAL-2026-5165
Source
OpenSSF Malicious Packages via OSV
Summary
Malicious code in @emcd-vue/loans (npm)
Details
Part of a coordinated multi-package supply-chain attack impersonating EMCD (emcd.io), a legitimate Russian cryptocurrency exchange and mining pool. The attacker registered the `@emcd-vue` npm scope to distribute multiple malicious packages posing as internal tooling. This package was published 90 seconds after sibling package `@emcd-vue/auth` on 2026-06-01 by the same anonymous account (`emcd-vue@proton.me`).
Confirmed to use identical infrastructure and dropper logic as `@emcd-vue/auth`: downloads a platform-specific second-stage payload from `https://oob.moika.tech/payload/{platform}` using `X-Secret: l95HdDaz3kQx1Zsg3WxH6HvKANf51RY1`, writes it to `~/.emcd-vue_init.js` (dot-prefixed hidden file), and executes it as a detached, unref'd process that persists after npm exits. Beacons installation metadata to `https://oob.moika.tech/report` on completion.
---
## Source: amazon-inspector (7b5f346a554fe9f5f7cfc733c36d4c92c373aea12e245ef70e1031f41ff76f05) On `npm install`, the declared postinstall script `scripts/postinstall.js` executes a heavily obfuscated (obfuscator.io-style) bundle that collects host identifiers (hostname, username, homedir), the full `process.env` (with Windows-specific keys such as USERDOMAIN, COMPUTERNAME, APPDATA, LOCALAPPDATA, TEMP, PROGRAMDATA), the tail of shell history, and the contents of a hardcoded list of files under the user's home directory that the package itself never created. The collected object is transmitted to a remote endpoint over HTTP(S) and additionally over a covert DNS channel: the payload is base32-encoded into subdomain labels and issued as `dns.Resolver().resolveTxt(...)` queries in chunks, bypassing HTTP egress filters. Endpoint hostnames, header names, and API strings are reconstructed at runtime via a shuffled string array with RC4/XOR decoders. Before exfiltrating, the script checks `process.argv` and `NODE_OPTIONS` for debugger indicators and performs a timing check to detect sandboxes, skipping the exfil if analysis instrumentation is detected. The package also exhibits dependency-confusion shape: metadata references an internal-looking scope and registry (`@emcd-vue`, `npm.emcd-vue.io`, `github.emcd-vue.io`) while being published to the public npm registry, and `dist/index.js` re-exports a `../src/index.js` that is absent from the tarball, so the package has no functional library surface — the postinstall is its only executable code.
Decision evidence
public snapshotAI called this Malicious at 96.0% confidence as Malware with low false-positive risk.
Evidence for block
- package.json defines postinstall: node scripts/postinstall.js
- scripts/postinstall.js is heavily obfuscated single-line code, unlike the small declared config-loader API
- scripts/postinstall.js references process.env and includes process.env in a telemetry payload object
- scripts/postinstall.js builds network calls with atob/wfdzqt-obfuscated strings and delayed execution
- README.md discloses install telemetry to telemetry.emcd-vue.io, but code sends full environment, not anonymous metadata
- dist/index.js requires ../src/index.js, but src/ is absent from the package
Evidence against
- No destructive file deletion observed in inspected files
- No explicit persistence mechanism observed
- No native binary or compiled addon files present
- README.md openly mentions install telemetry, but not full environment capture
Behavioral surface
DynamicRequireEnvironmentVars
MinifiedTrivial
NoLicense
Source & flagged code
3 flagged · loading sourcepackage.jsonView file
•scripts.postinstall = node scripts/postinstall.js
High
Install Time Lifecycle Scripts
Package defines install-time lifecycle scripts.
package.jsonView on unpkg•scripts.postinstall = node scripts/postinstall.js
Medium
Ambiguous Install Lifecycle Script
Install-time lifecycle script is not statically allowlisted and needs review.
package.jsonView on unpkgdist/index.jsView file
2// dist/index.js
L3: module.exports = require('../src/index.js');
Medium
Dynamic Require
Package source references dynamic require/import behavior.
dist/index.jsView on unpkg · L2Findings
1 High3 Medium3 Low
HighInstall Time Lifecycle Scriptspackage.json
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requiredist/index.js
MediumEnvironment Vars
LowNon Install Lifecycle Scripts
LowScripts Present
LowNo License