





























Socket proactively blocks malicious open source packages in your code.
A compromised release of the popular jscrambler npm package introduced hidden native binaries that execute automatically during npm install, exposing users to a supply chain attack before any application code runs.
The malicious 8.14.0 release, published on July 11, adds an undocumented preinstall hook that invokes dist/setup.js. It also introduces new files, including dist/setup.js and dist/intro.js, along with platform-specific binaries for Linux, macOS, and Windows embedded in an obfuscated CSI container. None of these files or the install hook exist in the previous release, 8.13.0.
Socket detected the compromised package 6 minutes after publication.
The package selects and executes one of three bundled binaries depending on whether it is installed on Windows, macOS, or Linux.
jscrambler@8.14.0preinstall hook executes code automatically during npm install.dist/setup.js and dist/intro.js) are entirely new in version 8.14.0.8.13.0.The compromised jscrambler package is used to integrate Jscrambler’s JavaScript code-protection tooling into application build pipelines. Developers commonly install it as a development dependency or invoke it through CI systems to process production builds.
Because the malicious code runs through a preinstall hook, simply installing jscrambler@8.14.0 is enough to trigger the bundled platform-specific binary. Users do not need to import the package or run the Jscrambler CLI.
This creates potential exposure across developer workstations, automated build systems, and CI environments. Depending on where the package was installed, the malicious binary may have executed with access to source code, environment variables, build credentials, deployment tokens, and other secrets available to the npm process.
The package receives approximately 15,800 weekly downloads, although the number of users who installed the compromised version is not yet known. Socket detected and flagged version 8.14.0 six minutes after it was published.
Users should remove jscrambler@8.14.0, rotate any credentials accessible to affected development or CI environments, review installation logs for execution of dist/setup.js, and revert to a verified clean release. Pin to version 8.13.0 or another verified clean release until the maintainers publish a remediation.
Socket has reported the compromised release to the Jscrambler maintainers, and a public tracking issue is available on GitHub: https://github.com/jscrambler/jscrambler/issues/322
The compromised version 8.14.0 ships two malicious files under dist/.
setup.js is a small loader that runs on install via a preinstall hook such that is gets executed whether or not the package is ever actually imported. intro.js, despite its name and .js extension, is not JavaScript at all. It is an approximately 7.8 MB large binary container marked with a custom five-byte header (1b 43 53 49 01, i.e. \x1bCSI\x01), whose sixth byte is a payload count.
The container packs three gzip-compressed native executables, one per operating system:
On install or run, setup.js:
process.platform..exe on Windows).spawn(..., { detached: true, stdio: 'ignore', windowsHide: true }) followed by unref().In plain terms: the loader silently drops and executes a native binary in the background, tailored to the victim's operating system.
The embedded executables are Rust-built, cross-platform infostealers (Linux x86-64, Windows x86-64, macOS arm64). Analysis of the payloads reveals a broad, developer-focused credential and secret harvester. Its sensitive configuration strings are individually encrypted with ChaCha20-Poly1305; we recovered approximately 2,400 of them.
The malware stores its sensitive strings encrypted (see String Obfuscation below). Once decrypted, the target surface is extensive and clearly oriented toward developer and cloud-operator machines — a rational choice for an npm-delivered payload, since the victims are developers.
Browser-extension wallets are targeted by their extension IDs:
nkbihfbeogaeaoehlefnkodbefgpgknnegjidjbpglichdcondbcbdnbeeppgdphhnfanknocfeofbddgcijnmhnfnkdnaadbfnaelmomeimhlpmgjnjophhpkkoljpaThe Exodus wallet (server.exodus.io) is also targeted. The config contains vault- and seed-extraction keys — HD Key Tree, mnemonic, seedPhrase, recoveryPhrase, and seed — plus scrypt KDF parameters (salt, iterations, N, r, p). This indicates an attempt to decrypt wallet vaults, not merely copy files.
A distinctive and current focus: the malware enumerates configuration for AI developer tooling, which frequently holds API keys and Model Context Protocol (MCP) server credentials. Targets include:
.config/Claude/claude_desktop_config.json, .claude.json.cursor/mcp.json.codeium/windsurf/mcp_config.json.factory/mcp.json.config/zed/settings.json, context_serverssettings.json, .mcp.json, mcpServersThe payload targets all three major clouds:
metadata.google.internal, the compute-metadata service-account token endpoint, GOOGLE_APPLICATION_CREDENTIALS, .config/gcloud, credentials.db, access_tokens.db, application_default_credentials.json, and Secret Manager access.169.254.170.2, secretsmanager.GetSecretValue / ListSecrets, and SSM Parameter Store AmazonSSM.GetParameters / DescribeParameters.169.254.169.254 and management.azure.com./api/v9/users/@me and guild enumeration..slack.com, /api/auth.test.tdata, key_datas.profiles.ini, cookies.sqlite, prefs.js.steamLoginSecure, loginusers.vdf, ConnectCache.sudo -S -p (password on stdin) and systemd-run --system --no-ask-password.crontab, and macOS LaunchAgents.check.torproject.org with /api/ip, the public resolvers 1.1.1.1 and 8.8.8.8, and machine fingerprinting via /etc/machine-id, /var/lib/dbus/machine-id, and /sys/class/dmi/id/board_serial.The malware's sensitive strings are not stored in cleartext. Each is individually encrypted with ChaCha20-Poly1305 (IETF, 12-byte nonce) and decrypted on demand into lazily initialized statics. Per string, the binary embeds:
.rodata (loaded in the decompiled code as a movups/movupd pair of adjacent 16-byte reads).movabs imm64 followed by a mov dword ptr [...], imm32)..rodata, whose trailing 16 bytes are the Poly1305 authentication tag.In the Linux binary, the per-string decrypt helper is at 0x1782f9, and a large lazy-initializer at 0x25c5e5 decrypts the wallet-targeting block into .bss statics. The standalone ChaCha20 core is at 0x425340; the config AEAD's Poly1305 clamp constant is at 0x2e2c0, distinct from the rustls TLS instance whose clamp is at 0xbaee0.
Because Poly1305 is an authenticator, a wrong key, nonce, or ciphertext boundary fails tag verification — decryption is self-validating. We recovered ~2,421 strings this way, cross-validated with two independent AEAD implementations (OpenSSL and libsodium) yielding byte-identical plaintext with zero tag mismatches. A reproduction outline is in the appendix.
Static analysis confirmed outbound exfiltration, carried over TLS via rustls. The payload contains a literal POST /upload HTTP/1.1 request with a multipart/form-data body, consistent with uploading harvested data to a drop server. It also constructs numerous POST/PUT requests that query cloud and orchestration APIs using stolen credentials: cloud metadata services, Kubernetes (/api/v1/namespaces), AWS Secrets Manager and SSM, and others.
• dist/setup.js —a742de963f14a92d24ebcbc7b44ac867e23a20d31d1b0094a13a4f83287f4e60
• dist/intro.js — a41a523ef9517aab37ed6eea0ec881821bdcb7aefcb5c5f603adc7907f868c86
• package.json — bba32ddeab075a5e5015eec50f5d2af364c95b848732c714aea6b6baf78f49f0
Decompressed native payload SHA-256
• Linux ELF — fbbcf4d8f98168f78f5c0c47a9ae56d59ec8ac84a7c9ca6b797fedfb8d62d2bd
• Windows PE — b7ca95d1b23c8e67416a25cedf741de0917c2096bbc9d24649eea7853d054903
• macOS Mach-O — c8fd47d36bdf7c825378593ab82ed8c24d1dc52e26b507812393e24e1d5201fd
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。