Table of contents
On 11 July 2026, an attacker published several malicious versions of our public jscrambler npm package, the command-line tool used with our Code Integrity product. The attacker had gained write access to the package's GitHub repository and used a GitHub Actions workflow to exfiltrate the npm token we use to publish the package. They then used that token to publish versions we did not authorise.
We detected the unauthorised publication within seconds, through automated notifications to our package maintainers, and began our incident response immediately. The malicious versions were deprecated straight away to stop further installation through normal dependency resolution, and we published a verified-clean version the same evening. We then worked with the npm security team, who removed the malicious versions from the registry.
What happened
An attacker compromised a Jscrambler developer's machine, which contained the developer's GitHub SSH key, as well as their npm publication credentials. The attacker then used these to publish a malicious version ofattack our public jscrambler npm package, the open-source command-line client used to interact with Code Integrity, and the four helper packages that depend on it.
The malicious versions of the jscrambler package were:
8.14.0
8.16.0
8.17.0
8.18.0
8.20.0
The helper packages had one version published referencing the compromised 8.18.0:
jscrambler-webpack-plugin 8.6.2
gulp-jscrambler 8.6.2
grunt-jscrambler 8.5.2
jscrambler-metro-plugin 9.0.2
The attacker's malicious code executed during package installation in the earlier versions (preinstall hook code), and on running the CLI in the later ones (attackers pivoted to changing the package code).
The current published version, 8.22.0, is verified clean and safe to use.
Please see the end of this report for a full timeline of events.
Why several versions appeared
Over a short period during our response, further malicious versions appeared after we had already published clean ones. When we first responded, we revoked the developer's npm credential we believed the attacker was using. In fact, they were publishing with the npm token they had exfiltrated through the GitHub Actions workflow, not the developer's credential, so each time we released a clean version, the attacker published a new malicious one. Once we identified that token as the credential actually in use, we revoked it and enforced the additional publishing controls described below. From that point, the attacker had no further access and no new malicious versions were published.
What was not affected
No Jscrambler product was affected.
No customer data was affected.
We have also not received a single report that any customer was impacted.
To reiterate a point that matters: the jscrambler package is the open-source command-line client used to interact with Code Integrity, and it is not the Code Integrity product or service itself. Only that CLI tool was affected. The Code Integrity platform was not compromised, and there are many ways of using Code Integrity that never involved the affected package versions at all.
Webpage Integrity and Iframe Integrity are separate products and were never at risk.
The jscrambler package sits outside our product infrastructure, and our investigation has found no evidence that our production or customer-facing systems, or customer data, were affected.
Attackers in this situation sometimes change the code itself. Using a forced push, they can even insert very old changes to the code. For that reason, we have also reviewed the full commit history of the package's repository and confirmed that our source code was not altered. The malicious versions were artifacts published with the stolen token, not changes to the code in our repository.
What you should do
If you use the Code Integrity jscrambler package, check whether you or any automated process installed one of the affected versions:
If you installed jscrambler at version 8.14.0, 8.16.0, 8.17.0, 8.18.0 or 8.20.0, treat it as an affected install.
If you installed any of the helper packages at the versions listed above, treat those as affected too, because they resolved to the compromised 8.18.0.
If you are affected, we recommend that you update to jscrambler 8.22.0 (or the current fixed versions of the dependent packages), reinstall from a clean state, and rotate any credentials that were available in the environment where the affected version ran, as a precaution.
If you only use Webpage Integrity or Iframe Integrity, no action is required.
Looking ahead, because the malicious versions were live only briefly before we replaced them with a clean release, teams that do not install brand-new versions the moment they are published would not have been exposed. Most package managers now support a minimum release age, sometimes called a cooldown, which holds back a newly published version until it has been available for a set number of days. npm supports this through its min-release-age setting and pnpm through minimumReleaseAge. Enabling it is a simple and effective way to reduce exposure to this class of supply-chain issue, and we recommend it.
What we have changed
We have enabled multi-factor authentication for npm releases made through our automated publishing pipeline. In practice, this means that a release produced by automation now requires a manual verification step before it is published, so no version can reach the public registry without a human check. We have also rotated all the relevant publishing credentials and hardened the surrounding processes.
Things that we started implementing immediately:
Pair npm publishing with OIDC – Uses short-lived, identity-based credentials instead of long-lived npm tokens for package publishing, eliminating a high-value secret from developer machines and significantly reducing the risk of token theft and unauthorized releases.
npm config set ignore-scripts true - Prevents preinstall and postinstall scripts from executing automatically, blocking one of the most common malware execution vectors in the npm ecosystem.
Scan for malicious packages and VS Code extensions – Continuously scans developers’ machines for known malicious packages and VS Code extensions, enabling early detection of compromised software.
Remove unnecessary keys and tokens from developer machines – Minimizes the number of credentials available on developer workstations, reducing the impact of credential theft.
Use min-release-age with pnpm – Delays the installation of newly published package versions, reducing exposure to freshly released malicious packages.
In addition, we are also planning the roll out of the following security controls:We're also reviewing all our publication processes methodically to …
Add dual control to critical release operations – Require two independent approvals for sensitive release actions, reducing the risk of unauthorized or malicious package publication.
Hardening existing multi-factor authentication processes - Use hardware tokens instead of time-based one-time passwords.
Canary tokens – Deploy decoy credentials that trigger an alert if accessed, providing early detection of malware searching for secrets.
Dev Containers – Isolate the development environment inside a container, limiting the ability of malicious dependencies to access the host system and developer credentials.
Further Container Hardening - Further remove permissions from our products containers, using read-only containers where applicable.
Closing
We hold ourselves to a high standard on security, and we know an incident like this affects the trust our customers place in us. We are sharing this openly because that is the right thing to do, and because it helps anyone who may have pulled an affected version take the right steps.
We would also encourage other package maintainers on GitHub and npm to take this as a prompt to review the controls protecting their own publishing pipelines. npm and GitHub have introduced a number of supply-chain security features over the past year, including trusted publishing with OIDC and two-factor authentication on publishing that also covers automated, token-based releases.
This kind of attack has become disturbingly common this year; barely a week goes by without another company disclosing something similar. It's a systemic problem right now: with AI coding tools in daily use, a developer's device has become a far more valuable target than it used to be, because it now holds more tokens, cached credentials, and standing access than ever before. Attackers know this, and are going after these targets aggressively across the industry. We were not an isolated case.
If you have questions or need help assessing your exposure, please contact us at [security contact].
We will update this post if there is further information our customers need.
Timeline
11 July 2026
Time (Portugal Time, UTC+1) | Event |
15:51 & 15:53 | Two failed GitHub "Release" automation runs on the employee's account - the first visible signs. |
16:12 | Malicious 8.14.0 published directly to npm. |
16:50 | SSH key removed from GitHub; 8.14.0 deprecated. |
18:10 | Clean 8.15.0 published. |
18:37 | Attacker publishes 8.16.0 and 8.17.0; malware removed from the laptop; email passwords and SSH keys rotated. |
18:45 | 8.18.0 collision: our clean publish and the attacker's malicious publish happened together; the attacker's landed first. |
18:50 | Attacker publishes 8.20.0. |
18:55 | Two-factor authentication enforced on npm publishing. |
19:12 | Stolen npm token identified and removed; clean 8.22.0 published. No attacker activity after this point. |
13 July 2026
Time | Event | |
09:37 | npm removed the malicious package versions. | |
10:02 | Confirmed the attacker exfiltrated the npm token via GitHub Actions using the stolen SSH key. | |
12:56 | Public reports that 8.18.0 is also infected. | |
13:23 | The four dependent packages pinned to 8.18.0 identified. |