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 their own modified versions directly to the npm registry.
We detected the unauthorized 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
A Jscrambler developer’s machine got compromised, and it contained the developer’s GitHub SSH key, as well as their npm publication credentials. The attacker then used these to publish a malicious version of 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 credentials 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.
As of the time of writing, npm reports 1,614 downloads across all affected packages. However, that doesn’t mean 1,614 people were affected. On average, we see approximately ~1,837 downloads of the Jscrambler cli package a day. However, on an average Saturday, this drops significantly – we saw an average of only ~391 downloads each Saturday in the 8 weeks leading up to the incident. This suggests that most of the downloads were probably security researchers investigating this incident, rather than affected installations, especially as some of these versions were the latest version for only a matter of minutes. We have 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 issues, and we recommend it.
What We Have Changed
Things that we started implementing immediately:
- Enabled multi-factor authentication for automated npm release – 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. Note this is different and on top of the existing MFA used by developers to access GitHub, npm etc.
- Rotated all relevant publishing credentials – whether compromised or not, and hardened the surrounding processes.
- Changed npm config to use 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.
- Scanned 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.
- Removed unnecessary keys and tokens from developer machines – Minimizes the number of credentials available on developer workstations, reducing the impact of credential theft.
- Used 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 rollout of the following security controls:
- 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.
- Pairing 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.
- 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 [email protected].
We will update this report 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 (Portugal Time, UTC+1) | Event |
| 09:37 | npm removed the malicious package versions. |
| 12:56 | Public reports that 8.18.0 is also infected. |
| 13:23 | The four dependent packages pinned to 8.18.0 identified. |