Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
Malicious package

@petitcode/eb-retrynpm

Malicious code in @petitcode/eb-retry (npm) Remove it immediately and rotate any exposed credentials.

MAL-2026-6310
Immediate action
Remove the package, then rotate any secrets the build/runtime could reach.
npm uninstall @petitcode/eb-retry

What this malware does

@petitcode/eb-retry (malicious version 1.3.5, published by [email protected]) is a trojanized npm package belonging to the wshu.net credential-stealer campaign. The campaign published trojanized look-alike utility packages across 12+ scopes whose publisher accounts all follow the pattern <scope>-<6 random chars>@wshu.net, with every scope created on June 4, 2026 in a ~40-minute burst. This package masquerades as a retry wrapper (a decoy copy of the popular retry utility) and ships real, working utility code so it passes a glance, while bundling a much larger malicious payload at lib/warmup.js. package.json declares a postinstall hook ("node lib/warmup.js") that runs the payload automatically on npm install. It is additionally a dual-trigger variant: even if postinstall is skipped with --ignore-scripts, the payload still executes at require-time the first time application code calls retry(). The payload is heavily obfuscated with javascript-obfuscator (hex-named identifiers, a while (!![]) array-rotation IIFE, base64+RC4 string decoding, control-flow flattening, and runtime-decrypted module resolution to stay out of the static module graph). At runtime it is a Chromium browser credential stealer: it reads Chromium Cookies and Login Data and decrypts saved passwords protected by AES-256-GCM (the v10/v11 app-bound key schemes), then exfiltrates them over HTTPS using a spoofed Mozilla/5.0 user agent. Malicious payload lib/warmup.js SHA-256: 32d02f806d58a6670f7cc9b93f1d85b22e0e0f535e1f90a62d86918033896f54.

Package advertises itself as a small retry/exponential-backoff helper (lib/index.js is ~50 lines) but ships a 282KB obfuscator.io-packed lib/warmup.js (and matching lib/warmup.mjs at 250KB) whose runPrepare() is invoked unconditionally on every require('@petitcode/eb-retry'). The same file is self-executing as a standalone script via if (require.main === module) onInstall(); so it also runs during postinstall flows. The packed code contains AES-256-GCM decryption of an embedded encrypted blob (which carries a remote URL), an HTTPS fetch of additional payload bytes, and a child_process.spawn of process.execPath with the original argv — i.e. it re-runs Node against attacker-supplied code. Obfuscator.io packing (1267-element rotated string array, RC4-style decoder, control-flow flattening, self-defending console overrides, debug-protection timer that crashes under devtools/inspector) is used to hide the URL, key derivation, and exec invocation. The package.json points repository, bugs, and homepage URLs at github.com/tim-kos/node-retry — an unrelated legitimate project by Tim Koschützki — while the actual publisher is petitcode <[email protected]>, a deliberate impersonation to lure developers searching for retry utilities. Any installer that runs npm install @petitcode/eb-retry or any code path that requires the package will execute the dropper.

Malicious versions

4 flagged
1.3.31.3.41.3.51.3.6

Indicators of compromise (SHA-256)

39f6df9234ec7224f9094f0532931550e76edb000f9773185a83732086bcc4af
3fc2453be99614e7494cc5648d430003db18fb7f9b488b0988aa308da80ed1d8
4386267addad1d2b89d4d471966e028ea201469edd6ece252f9710cd679c20aa
6f68260c08dfaaf8fe42a04a761e46f9d7397f29c751dd673cb87a04cfa7af14

Detection & response playbook

Credential / info stealer
  1. Find it

    Scan your lockfiles (package-lock.json, pnpm-lock.yaml, yarn.lock, requirements.txt, poetry.lock, etc.) and build artifacts for @petitcode/eb-retry (4 malicious versions). O3 Security's supply-chain scanner checks every dependency against known-malicious package intelligence at install time and in CI, flagging @petitcode/eb-retry across your stack and pipelines.

  2. If you installed it — respond

    @petitcode/eb-retry is built to steal secrets, so assume every credential the build or runtime could read is compromised. Remove it from your project and lockfile, then rotate ALL exposed secrets — npm/registry tokens, cloud keys, CI/CD secrets, SSH keys, and any .env values — from a known-clean machine. Audit logs for unauthorized use of those credentials.

  3. Did it already run?

    If @petitcode/eb-retry was ever installed, its post-install/runtime payload may have already executed. O3's L7 egress monitoring and runtime eBPF sensors detect the credential exfiltration or command-and-control callback after install and block the malicious outbound channel, so you catch and contain the actual compromise — not just the presence of the package.

  4. How O3 protects you

    O3 blocks @petitcode/eb-retry before install through its supply-chain scanner, and if it has already run, detects and severs the exfiltration or C2 callback at runtime through L7 egress monitoring and eBPF.

Frequently asked questions

No. @petitcode/eb-retry on npm has been identified as a malicious package (versions 1.3.3, 1.3.4, 1.3.5, 1.3.6 flagged). It should be removed immediately — do not install or keep it in your dependency tree.

Campaign

IN-MAL-2026-007325IN-MAL-2026-007280IN-MAL-2026-007288IN-MAL-2026-007330

References

Credits

  • Amazon Inspector · finder
  • SafeDep · finder

Detect & block this

O3 blocks @petitcode/eb-retry-class packages before install and in CI — and if it already ran, its runtime egress monitoring catches the credential exfiltration and severs the channel.

@petitcode/eb-retry (npm) malicious package — MAL-2026-6310 | O3 Security