On July 11, 2026, five versions of jscrambler — a commercial JavaScript obfuscation and code-protection tool used by enterprises to harden their JavaScript against reverse engineering — were published to npm carrying a cross-platform Rust infostealer. The attack is notable not only because a security vendor was weaponized against its own customers, but because the malware evolved in real-time across five releases to bypass --ignore-scripts and pnpm's allowScripts policy. By the final two versions, the dropper had migrated entirely to require()-time injection inside the package's own JavaScript files — a technique that defeats every install-time scanner.

Le 11 juillet 2026, cinq versions de jscrambler — un outil commercial d'obfuscation JavaScript et de protection de code utilisé par les entreprises pour protéger leur JavaScript contre la rétro-ingénierie — ont été publiées sur npm avec un infostealer Rust multiplateforme. L'attaque est remarquable non seulement parce qu'un fournisseur de sécurité a été utilisé comme arme contre ses propres clients, mais parce que le malware a évolué en temps réel sur cinq versions pour contourner --ignore-scripts et la politique allowScripts de pnpm. Dans les deux dernières versions, le dropper s'était entièrement migré vers une injection au moment du require() — une technique qui déjoue tous les scanners d'install.

Socket detected version 8.14.0 six minutes after it was published. The package records approximately 60,000 monthly downloads. The clean versions to use are 8.15.0 (interim, released by maintainers to reclaim the latest tag mid-incident) and the final clean 8.22.0. Any machine that installed versions 8.14.0, 8.16.0, 8.17.0, 8.18.0, or 8.20.0 must be treated as fully compromised and rotated immediately.

Socket a détecté la version 8.14.0 six minutes après sa publication. Le package enregistre environ 60 000 téléchargements mensuels. Les versions propres à utiliser sont 8.15.0 (intermédiaire, publiée par les mainteneurs pour reprendre le tag latest en milieu d'incident) et la version finale propre 8.22.0. Toute machine ayant installé les versions 8.14.0, 8.16.0, 8.17.0, 8.18.0 ou 8.20.0 doit être considérée comme entièrement compromisée et toutes les clés/tokens rotation immédiatement.

5
malicious versions published July 11, 2026
versions malveillantes publiées le 11 juillet 2026
Source: Socket.dev, SafeDep, 2026
6 min
time to detection by Socket after first publish
délai de détection par Socket après la première publication
Source: Socket.dev blog, 2026
60K
monthly downloads of jscrambler npm package
téléchargements mensuels du package jscrambler npm
Source: npm registry, July 2026
7.8 MB
malicious binary container (3 platform payloads)
conteneur binaire malveillant (3 payloads de plateformes)
Source: Socket.dev technical analysis, 2026

What Is jscrambler and Why Does This Attack Matter?

Qu’est-ce que jscrambler et pourquoi cette attaque est-elle importante ?

Jscrambler is a commercial JavaScript security platform that enterprises use to protect their client-side code from reverse engineering, IP theft, and tampering. Its npm package, jscrambler, is the CLI client that development teams install in their build pipelines to submit code to the Jscrambler API for obfuscation before deployment. Customers include financial institutions, gaming companies, and retailers that embed obfuscated JavaScript into public-facing web applications.

Jscrambler est une plateforme de sécurité JavaScript commerciale que les entreprises utilisent pour protéger leur code côté client contre la rétro-ingénierie, le vol de propriété intellectuelle et la falsification. Son package npm, jscrambler, est le client CLI que les équipes de développement installent dans leurs pipelines de build pour soumettre le code à l'API Jscrambler pour obfuscation avant le déploiement. Les clients incluent des institutions financières, des entreprises de jeux vidéo et des détaillants qui embarquent du JavaScript obscurci dans leurs applications web publiques.

This attack matters for two interlocking reasons. First, the trust paradox: a tool that developers rely on for security was turned into the delivery mechanism for an infostealer. Developers who run security-focused tooling in their CI pipelines are typically more security-conscious than average — yet that same consciousness may have caused them to whitelist jscrambler's install scripts without scrutiny. Second, the technique evolution: the attackers shipped five distinct variants in a single day, iterating their evasion strategy faster than most security teams can respond.

Cette attaque importe pour deux raisons interliées. Premièrement, le paradoxe de confiance : un outil sur lequel les développeurs comptent pour la sécurité a été transformé en vecteur de livraison d'un infostealer. Les développeurs qui exécutent des outils orientés sécurité dans leurs pipelines CI sont généralement plus consciencieux en matière de sécurité que la moyenne — mais cette même conscience peut les avoir amenés à mettre sur liste blanche les scripts d'installation de jscrambler sans examen approfondi. Deuxièmement, l'évolution des techniques : les attaquants ont livré cinq variantes distinctes en une seule journée, faisant évoluer leur stratégie d'évasion plus vite que la plupart des équipes de sécurité ne peuvent réagir.

Attack Timeline: 5 Versions, 1 Day, 3 Evasion Pivots

Chronologie de l’attaque : 5 versions, 1 journée, 3 pivots d’évasion

StepSecurity and SafeDep both confirmed that there is no matching commit, tag, or pull request in jscrambler's GitHub repository for version 8.14.0 — the version was pushed directly to the npm registry under a legitimate maintainer account, bypassing the project's normal release workflow. The entry point for the attackers was either the maintainer's npm account credentials or a compromised CI/CD token with publish rights.

StepSecurity et SafeDep ont tous deux confirmé qu'il n'existe aucun commit, tag ou pull request correspondant dans le dépôt GitHub de jscrambler pour la version 8.14.0 — la version a été poussée directement sur le registre npm sous un compte de mainteneur légitime, en contournant le workflow de publication normal du projet. Le point d'entrée pour les attaquants était soit les identifiants du compte npm du mainteneur, soit un token CI/CD compromis avec les droits de publication.

Here is how the attack evolved across the five malicious versions, all published on July 11, 2026:

Voici comment l'attaque a évolué sur les cinq versions malveillantes, toutes publiées le 11 juillet 2026 :

Attack Evolution — jscrambler versions, July 11, 2026
Évolution de l'attaque — versions jscrambler, 11 juillet 2026
Version 8.14.0 — Preinstall hook (initial)
  "scripts": { "preinstall": "node dist/setup.js" }
  dist/intro.js → 7.8 MB container (3 gzip binaries: Linux/macOS/Windows)
  setup.js → selects OS binary, writes to /tmp/, chmod +x, executes detached
  Detected by Socket: 6 minutes after publish ✓

Version 8.15.0 — CLEAN (maintainers reclaim 'latest' tag mid-incident)

Version 8.16.0 — Preinstall hook (continued)
  Same mechanism as 8.14.0, identical binary payload

Version 8.17.0 — Preinstall hook + pnpm allowScripts bypass
  Adds logic to detect pnpm environment and bypass allowScripts policy

Version 8.18.0 — ⚠️ PIVOT: require()-time injection
  Install hook REMOVED entirely
  Dropper injected as self-executing function at top of dist/index.js
  Fires on: require('jscrambler') or running jscrambler CLI
  Bypasses: --ignore-scripts, npm v12 blocking, pnpm allowScripts
  Bypasses: ALL install-time scanners

Version 8.20.0 — require()-time injection (continued)
  Same require()-time technique, also in dist/bin/jscrambler.js

Version 8.22.0 — CLEAN (final clean release by maintainers)

The pivot from preinstall hook to require()-time injection in 8.18.0 is the most significant detail of this incident. It means that even a development machine that ran npm install --ignore-scripts or a pnpm install with allowScripts: false would have been infected the first time a developer ran the jscrambler CLI or imported the package in a build script.

Le pivot du hook preinstall vers l'injection au moment du require() dans la version 8.18.0 est le détail le plus significatif de cet incident. Cela signifie que même une machine de développement ayant exécuté npm install --ignore-scripts ou une installation pnpm avec allowScripts: false aurait été infectée la première fois qu'un développeur aurait exécuté le CLI jscrambler ou importé le package dans un script de build.

The Payload: A Cross-Platform Rust Infostealer with eBPF Persistence

Le payload : un infostealer Rust multiplateforme avec persistance eBPF

All five malicious versions carry an identical payload container — dist/intro.js, a 7.8 MB file that packs three gzip-compressed native binaries compiled in Rust, one each for Linux, macOS, and Windows. The setup logic selects the correct binary at runtime based on process.platform, extracts it to the system temp directory under a random filename, marks it executable, and launches it detached — hiding its stdout and stderr from the parent process.

Les cinq versions malveillantes portent un conteneur de payload identique — dist/intro.js, un fichier de 7,8 Mo qui emballe trois binaires natifs compressés en gzip compilés en Rust, un pour Linux, macOS et Windows respectivement. La logique de configuration sélectionne le bon binaire à l'exécution en se basant sur process.platform, l'extrait dans le répertoire temporaire système sous un nom aléatoire, le rend exécutable et le lance en détaché — masquant son stdout et stderr au processus parent.

The infostealer's credential-harvesting targets, as documented by Socket and The Hacker News:

Les cibles de récolte de credentials de l'infostealer, telles que documentées par Socket et The Hacker News :

The collected data is compressed and exfiltrated to an attacker-controlled drop server over TLS, making detection via network egress monitoring difficult without explicit domain allowlisting.

Les données collectées sont compressées et exfiltrées vers un serveur drop contrôlé par l'attaquant via TLS, ce qui rend la détection par la surveillance de l'égress réseau difficile sans liste blanche de domaines explicite.

Platform-Specific Persistence Mechanisms

Mécanismes de persistance spécifiques à chaque plateforme

Beyond credential harvesting, the binaries implement aggressive persistence that survives reboots:

Au-delà de la récolte de credentials, les binaires implémentent une persistance agressive qui survit aux redémarrages :

Persistence Mechanisms by Platform
Mécanismes de persistance par plateforme
Windows:
  → Hidden Windows Task Scheduler task (re-executes every minute)
  → Anti-debugging checks to detect sandbox/analysis environments

macOS:
  → LaunchAgent plist in ~/Library/LaunchAgents/ (reloads on login)
  → Anti-debugging checks

Linux:
  → eBPF program loaded into the kernel from memory (!)
  → No filesystem trace — operates at kernel level

The Linux eBPF persistence is the most alarming element of the payload. Loading an eBPF program from memory without writing to disk means traditional filesystem-based forensics and antivirus scanning will find nothing on an infected Linux machine. This technique, previously associated with nation-state-level malware, appearing in an npm supply chain attack signals a significant escalation in attacker sophistication.

La persistance eBPF Linux est l'élément le plus alarmant du payload. Charger un programme eBPF depuis la mémoire sans écrire sur le disque signifie que la forensique traditionnelle basée sur le système de fichiers et les antivirus ne trouveront rien sur une machine Linux infectée. Cette technique, précédemment associée aux malwares de niveau étatique, apparaissant dans une attaque supply chain npm signale une escalade significative dans la sophistication des attaquants.

Why --ignore-scripts and npm v12 Are Not Enough

Pourquoi --ignore-scripts et npm v12 ne suffisent pas

The jscrambler attack directly challenges the assumption that blocking install scripts provides meaningful protection against supply chain attacks. npm v12, which ships in July 2026 with install scripts disabled by default, stops attacks delivered via preinstall and postinstall hooks. But the require()-time injection technique used in jscrambler 8.18.0 and 8.20.0 is completely unaffected by this protection.

L'attaque jscrambler remet directement en cause l'hypothèse selon laquelle le blocage des scripts d'installation fournit une protection significative contre les attaques supply chain. npm v12, qui sort en juillet 2026 avec les scripts d'installation désactivés par défaut, stoppe les attaques livrées via les hooks preinstall et postinstall. Mais la technique d'injection au moment du require() utilisée dans jscrambler 8.18.0 et 8.20.0 n'est pas du tout affectée par cette protection.

Here is a comparison of what each defense layer stops — and what it misses:

Voici une comparaison de ce que chaque couche de défense arrête — et ce qu'elle rate :

Defense Layer Comparison
Comparaison des couches de défense
Attack Vector         npm install    --ignore-scripts   npm v12 default   Runtime scanner
─────────────────────────────────────────────────────────────────────────────────────────
preinstall hook           ✗ RUN          ✓ BLOCKED          ✓ BLOCKED        N/A
postinstall hook          ✗ RUN          ✓ BLOCKED          ✓ BLOCKED        N/A
pnpm allowScripts bypass  ✗ RUN          varies             varies           N/A
require()-time injection  ✗ NOT fired    ✗ NOT fired        ✗ NOT fired      ✓ DETECT*

* Runtime scanners (Socket, Snyk) that inspect code at publish time or import time
  can detect the self-executing function injection before it runs.

This is why publish-time scanning is a critical defense layer that install-time protections cannot replace. Socket detected jscrambler 8.14.0 within 6 minutes of publication because it analyzes package code at the point of publish, not install. By the time a developer runs npm install, the decision to allow or block the package has already been made.

C'est pourquoi l'analyse au moment de la publication est une couche de défense critique que les protections au moment de l'installation ne peuvent pas remplacer. Socket a détecté jscrambler 8.14.0 dans les 6 minutes suivant sa publication parce qu'il analyse le code du package au moment de la publication, pas de l'installation. Au moment où un développeur exécute npm install, la décision d'autoriser ou de bloquer le package a déjà été prise.

The Trust Paradox: When Your Security Tool Is the Attack Vector

Le paradoxe de confiance : quand votre outil de sécurité est le vecteur d'attaque

Security Boulevard summarized this incident with the headline: "A Security Vendor Becomes the Supply Chain Risk." This is not a rhetorical flourish — it describes a real structural problem in how development teams make trust decisions about dependencies.

Security Boulevard a résumé cet incident avec le titre : "Un fournisseur de sécurité devient le risque de la supply chain." Ce n'est pas une figure de style — cela décrit un problème structurel réel dans la façon dont les équipes de développement prennent des décisions de confiance concernant les dépendances.

When a developer uses a tool called "jscrambler" — a tool whose entire purpose is to protect JavaScript against tampering and malicious modification — they are primed to trust it. The cognitive bias is understandable: a security vendor obviously cares about security. This same logic has been exploited across multiple 2026 attacks: the Miasma campaign targeted @redhat-cloud-services (a trusted infrastructure vendor), TrapDoor poisoned .cursorrules and CLAUDE.md files (developer security configurations), and now jscrambler (a security product) carries an infostealer.

Quand un développeur utilise un outil appelé "jscrambler" — un outil dont l'objectif est de protéger le JavaScript contre la falsification et les modifications malveillantes — il est prédisposé à lui faire confiance. Le biais cognitif est compréhensible : un fournisseur de sécurité se soucie évidemment de la sécurité. Cette même logique a été exploitée dans plusieurs attaques de 2026 : la campagne Miasma a cibleé @redhat-cloud-services (un fournisseur d'infrastructure de confiance), TrapDoor a empoisonné les fichiers .cursorrules et CLAUDE.md (configurations de sécurité des développeurs), et maintenant jscrambler (un produit de sécurité) transporte un infostealer.

The pattern is clear: attackers deliberately target high-trust packages because they are least likely to be scrutinized. "We trust jscrambler — it's a security tool" is exactly the reasoning that makes it a high-value target.

Le pattern est clair : les attaquants ciblent délibérément les packages à haute confiance parce qu'ils sont les moins susceptibles d'être examinés. "Nous faisons confiance à jscrambler — c'est un outil de sécurité" est exactement le raisonnement qui en fait une cible à haute valeur.

Incident Response: What To Do If You Installed an Affected Version

Réponse à l’incident : que faire si vous avez installé une version affectée

If any machine in your organization installed jscrambler versions 8.14.0, 8.16.0, 8.17.0, 8.18.0, or 8.20.0, treat it as fully compromised. The severity is high because the payload targets the exact credentials most damaging in a production breach context.

Si une machine de votre organisation a installé les versions jscrambler 8.14.0, 8.16.0, 8.17.0, 8.18.0 ou 8.20.0, traitez-la comme entièrement compromise. La sévérité est élevée car le payload cible les credentials exactement les plus dommageables dans un contexte de breach en production.

Immediate Actions (Priority Order)
Actions immédiates (ordre de priorité)
# 1. Identify exposure
grep -r "jscrambler" package-lock.json yarn.lock pnpm-lock.yaml
npm ls jscrambler  # shows installed version

# 2. Check lockfile for affected versions
# Affected: 8.14.0, 8.16.0, 8.17.0, 8.18.0, 8.20.0
# Safe: 8.15.0, 8.22.0+

# 3. If affected version installed — rotate ALL credentials on that machine:
# - AWS: aws iam create-access-key, invalidate old
# - GitHub: revoke all personal access tokens, create new
# - npm: npm token revoke <token>, generate new
# - SSH: rotate all keys that were on the machine
# - Bitwarden: change master password, check access logs
# - AI tools: revoke Claude Desktop and Cursor auth tokens

# 4. On Linux — check for eBPF persistence
bpftool prog list  # list loaded eBPF programs
# Look for unnamed or suspiciously named programs
# May require kernel-level memory forensics

# 5. Upgrade to safe version
npm install jscrambler@8.22.0

# 6. Pin the version in package.json (remove semver range)
# Change: "jscrambler": "^8.x.x" → "jscrambler": "8.22.0"

Prevention Checklist: Defending Against Require()-Time Injection

Checklist de prévention : se protéger contre l’injection require()-time

This attack demonstrates that blocking install scripts alone is insufficient. A complete defense requires multiple complementary layers:

Cette attaque démontre que bloquer les scripts d'installation seuls est insuffisant. Une défense complète nécessite plusieurs couches complémentaires :

Frequently Asked Questions

Questions fréquentes

Which jscrambler versions are safe to use?

Quelles versions de jscrambler sont sûres à utiliser ?

The safe versions are 8.15.0 (an interim clean release published by maintainers to reclaim the latest tag mid-incident) and 8.22.0 (the final clean release). The malicious versions are 8.14.0, 8.16.0, 8.17.0, 8.18.0, and 8.20.0. We recommend pinning to 8.22.0 exactly in your package.json.

Les versions sûres sont 8.15.0 (une version propre intermédiaire publiée par les mainteneurs pour récupérer le tag latest en milieu d'incident) et 8.22.0 (la version propre finale). Les versions malveillantes sont 8.14.0, 8.16.0, 8.17.0, 8.18.0 et 8.20.0. Nous recommandons de fixer exactement 8.22.0 dans votre package.json.

Does npm install --ignore-scripts protect against this attack?

npm install --ignore-scripts protège-t-il contre cette attaque ?

Partially. It blocks the preinstall hook used in versions 8.14.0–8.17.0. But versions 8.18.0 and 8.20.0 use require()-time injection — the dropper fires when you run the jscrambler CLI or import the package, not when you install it. --ignore-scripts has no effect on this vector.

Partiellement. Cela bloque le hook preinstall utilisé dans les versions 8.14.0–8.17.0. Mais les versions 8.18.0 et 8.20.0 utilisent l'injection au moment du require() — le dropper se déclenche quand vous exécutez le CLI jscrambler ou importez le package, pas quand vous l'installez. --ignore-scripts n'a aucun effet sur ce vecteur.

Does npm v12's install script blocking stop this?

Le blocage des scripts d’installation de npm v12 arrête-t-il cela ?

No for versions 8.18.0 and 8.20.0. npm v12 blocks preinstall/postinstall scripts by default — an important improvement that stops the first three malicious versions. But require()-time injection (which fires on first use, not on install) is completely outside npm v12's threat model. This is a deliberate evasion by the attacker.

Non pour les versions 8.18.0 et 8.20.0. npm v12 bloque les scripts preinstall/postinstall par défaut — une amélioration importante qui stoppe les trois premières versions malveillantes. Mais l'injection au moment du require() (qui se déclenche à la première utilisation, pas à l'installation) est complètement en dehors du modèle de menace de npm v12. Il s'agit d'une évasion délibérée de l'attaquant.

How can I tell if my Linux machine is infected with the eBPF payload?

Comment savoir si ma machine Linux est infectée par le payload eBPF ?

Traditional antivirus and filesystem scanning will find nothing because the eBPF program runs in kernel memory without writing to disk. Run bpftool prog list to list all loaded eBPF programs and look for unnamed or suspiciously named entries. If you have installed an affected version on a Linux machine, rotate all credentials regardless and isolate the machine for deeper forensic analysis. A kernel memory dump may be required for complete confidence.

Les antivirus traditionnels et l'analyse du système de fichiers ne trouveront rien car le programme eBPF s'exécute dans la mémoire du noyau sans écrire sur le disque. Exécutez bpftool prog list pour lister tous les programmes eBPF chargés et recherchez les entrées sans nom ou avec des noms suspects. Si vous avez installé une version affectée sur une machine Linux, effectuez la rotation de tous les credentials quoi qu'il arrive et isolez la machine pour une analyse forensique approfondie. Un dump de la mémoire du noyau peut être nécessaire pour une confiance complète.

Why did the attacker target Claude Desktop and Cursor config files?

Pourquoi l'attaquant a-t-il ciblé les fichiers de configuration Claude Desktop et Cursor ?

AI coding assistant config files contain OAuth tokens and session credentials that are typically long-lived and provide access to powerful capabilities. A Claude Desktop or Cursor authentication token can be used to submit requests on behalf of a developer, access premium API tiers, or — in the case of agentic tools — execute code and read file systems. This pattern has appeared in multiple 2026 attacks, including TrapDoor (which poisoned .cursorrules and CLAUDE.md via Unicode zero-width injection) and the Miasma Wave 3 that targeted Azure repos via AI agent config files.

Les fichiers de configuration des assistants de code IA contiennent des tokens OAuth et des credentials de session qui sont typiquement à longue durée de vie et fournissent l'accès à des capacités puissantes. Un token d'authentification Claude Desktop ou Cursor peut être utilisé pour soumettre des requêtes au nom d'un développeur, accéder aux niveaux d'API premium, ou — dans le cas des outils agentiques — exécuter du code et lire des systèmes de fichiers. Ce pattern est apparu dans plusieurs attaques de 2026, notamment TrapDoor (qui a empoisonné .cursorrules et CLAUDE.md via injection Unicode à largeur nulle) et Miasma Wave 3 qui ciblait les repos Azure via les fichiers de configuration des agents IA.

How do I know if my npm packages are being monitored for supply chain attacks like this?

Comment savoir si mes packages npm sont surveillés contre des attaques supply chain comme celle-ci ?

You need a combination of publish-time scanning (Socket.dev, Snyk, SafeDep) that catches malicious packages before install, and dependency monitoring (like CVE OptiBot) that watches your lockfiles for new CVEs and known-malicious versions. The jscrambler attack moved from publication to detection in 6 minutes — but that gap is long enough for a CI job to run and exfiltrate credentials if you have no automated alerting on your lockfile.

Vous avez besoin d'une combinaison d'analyse au moment de la publication (Socket.dev, Snyk, SafeDep) qui capture les packages malveillants avant l'installation, et de surveillance des dépendances (comme CVE OptiBot) qui surveille vos lockfiles pour les nouveaux CVE et les versions connues comme malveillantes. L'attaque jscrambler est passée de la publication à la détection en 6 minutes — mais ce laps de temps est suffisant pour qu'un job CI s'exécute et exfiltre des credentials si vous n'avez pas d'alerte automatisée sur votre lockfile.

Monitor Your Dependencies Before the Next jscrambler

Surveillez vos dépendances avant le prochain jscrambler

CVE OptiBot scans your package-lock.json, pnpm-lock.yaml, and yarn.lock files daily against OSV.dev and NVD, and alerts you the moment a package in your lockfile is flagged as malicious or vulnerable. The jscrambler attack was published, detected, and pulled — all in under an hour. Without automated lockfile monitoring, your team would not know until it was too late.

CVE OptiBot scanne vos fichiers package-lock.json, pnpm-lock.yaml et yarn.lock quotidiennement contre OSV.dev et NVD, et vous alerte dès qu'un package dans votre lockfile est signalé comme malveillant ou vulnérable. L'attaque jscrambler a été publiée, détectée et retirée — le tout en moins d'une heure. Sans surveillance automatisée du lockfile, votre équipe ne le saurait pas avant qu'il soit trop tard.

Start free monitoring Démarrer le monitoring gratuit