On 4 August 2026, version 11.1.6 of file-entry-cache added a preinstall
script and a 727KB obfuscated source file to a package that had neither. npm removed the version
the same day. Here is exactly what our scanner saw, what we can and cannot say about it, and how
to check whether it reached your builds.
file-entry-cache is a small, old, extremely widely depended-upon npm package — the
kind that arrives in your node_modules because something else you installed wanted
it. It does not normally run code at install time, and it does not normally ship obfuscated
source.
Version 11.1.6 did both. Our scanner compares each new version against its predecessor rather than judging it in isolation, and the delta is the whole story here: these are capabilities the package did not previously have.
| Signal | Evidence |
|---|---|
| Install hook | "preinstall": "node setup.mjs" |
| Minified source outside a build directory | longest line 727,662 characters |
| javascript-obfuscator string-array rotation | self-defending obfuscation, the tool's characteristic rotating string table |
A preinstall script runs automatically, before anything is built or audited, with
the permissions of whoever ran npm install — a developer laptop or a CI runner
holding deploy credentials. Obfuscation is not itself malicious; plenty of legitimate packages
ship minified bundles. What makes this combination worth acting on is that all three appeared
at once, in a package that had shipped neither for years.
What we are not claiming. We have not published an analysis of what the obfuscated code does, and we are not naming a responsible party. A package that has been maintained cleanly for years and suddenly gains an install hook is far more often a stolen publishing credential than a maintainer decision — the person whose name is on the release is usually the first victim, not the author. The finding here is the anomaly and its timing.
We analyse new versions from the public registries continuously and compare each against the version before it. The timeline, in UTC on 4 August 2026:
| Time (UTC) | Event |
|---|---|
10:19:39 | We grade 11.1.6 malicious on the delta above |
11:48:03 | Our takedown watcher confirms the version is still on npm |
11:52:08 | Next poll: the version is gone |
So npm removed it somewhere inside a four-minute window, between 1h28m and 1h33m after we
flagged it. We are giving the window rather than a single removal time because we only know
what our polling observed — the registry does not announce the moment it acts, and quoting
11:52:08 as “the time npm removed it” would be reporting our poll schedule as if
it were their decision. At the point we recorded the finding, no public advisory covered it.
One has since been published: OSV lists MAL-2026-11970, “Malicious code in file-entry-cache (npm)”. We are noting that deliberately — our detection came first, but the independent advisory is what turns our signal-level finding into a confirmed one, and a write-up that quietly omitted it would be selling the detection harder than the evidence warrants.
We are publishing now, well after the fact, because the affected version is already gone from the registry — the remaining value is to the people who installed it in the window it was live, or who have it pinned in a lockfile.
Search your lockfiles and installed tree for the exact version:
grep -n "file-entry-cache" package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null
npm ls file-entry-cache
If you see 11.1.6, that install ran setup.mjs as a preinstall step.
Any long-lived credential that was present in that environment — npm tokens, cloud keys, CI
secrets, SSH keys — should be treated as exposed and rotated. Reinstall on a version other
than 11.1.6; npm has removed it, so a fresh resolve will not select it.
If you do not see 11.1.6, no action is needed. The package itself remains fine; a single version was affected.
Every individual signal here is common in benign software. Minified files are everywhere. Install hooks are used by legitimate native modules. The javascript-obfuscator library is a commercial product with paying customers who are not attackers. Scanning for any one of them produces mostly false positives, which is why an alert built on obfuscation alone teaches people to ignore alerts.
What is rare is a package acquiring all three in a single version after years without them. That is not a property of the code; it is a property of the change. It is also why the question we ask of every new release is not "does this look dangerous" but "is this package still doing what it was doing yesterday".
Detection, the version-delta analysis and the timeline are ours. The affected version was removed from npm on the same day we flagged it; we have not attributed it to anyone and have not published the payload. More research at nithic.ai/research.