Fourteen Months, No Advisory: MALFEX Shows Package Takedowns Stop at the Dependency Edge
CloudSEK published MALFEX on 30 September 2026: at least twelve npm packages and one GitHub payload repository, published between August 2023 and September 2026 by a single operator using Portuguese-language accounts. Five of the packages carry OSV malware advisories. Three are malicious with no advisory at all. Four are benign tools the operator ships as cover.
The attribution work is the headline, but it is not the part defenders can act on. The actionable finding is structural, and it is checkable against the public registry without taking CloudSEK's word for anything: the ecosystem's takedown machinery removes the package that was reported and leaves the package that was named inside the report.
The two gaps, verified against npm and OSV
We queried the npm registry and OSV directly on 1 October 2026. Both gaps hold.
function-flag— a livepostinstall, no advisory, since July 2025. The registry metadata for version 1.7.3 lists"postinstall": "node example.js"and pulls inaxios,child_process,figletandchalk. It was published 4 August 2025; the package itself dates to 30 June 2024 and has nine versions. An OSV query for the package name returns no advisories. The README is the operator signing their own work — "criado com muito amor e dedicação pela equipe Malfex, cujo dono é Murizada" — which is how CloudSEK tied the campaign's hardcodedmalfexteam2027key-derivation constant to a team name rather than a random string.cdn-img-fetch— advised, named as a dependency, and still shipping. Amazon Inspector's MAL-2026-17216 forimg-to-native, published 28 September 2026, explicitly namescdn-img-fetchas the sole dependency staging the payload, and flags that the caret range^1.0.0means "future 1.x releases can silently change the delivered payload bytes."img-to-nativeis now the familiar0.0.1-securitytombstone.cdn-img-fetchgot its own advisory, MAL-2026-17320, only on 30 September — two days later — and that advisory covers versions 1.0.0 and 1.0.1 only. Versions 1.0.2, 1.0.3 and 1.0.4 were published on 28 and 30 September and sit outside the advisory's affected range. The package was last modified at 23:07 UTC on 30 September.function-color— the wrapper nobody looked at. Two versions, latest 1.7.3 from 4 August 2025. It declares exactly one meaningful dependency:"function-flag": "^1.7.3". No advisory. Installing it installs the fourteen-month postinstall transitively.
The advised dropper trio CloudSEK names for delivery arm A — tlxbnhd, tldriver, mxdriver — are all unpublished on the registry, zero versions remaining, modified 22 September 2026. The seizure worked where it was pointed. It was pointed at three of twelve names.
What MAL-2026-17320 actually describes
Worth reading the Amazon Inspector text rather than the severity label, because it is a precise description of a staging primitive rather than a payload. On require(), cdn-img-fetch's index.js fires an immediately-invoked https.get against raw.githubusercontent.com/cavecrew/proj/main/banner.png and writes the response into a hidden dot-file in the OS temp directory. The advisory's own assessment:
"The current fetched bytes are written but not executed in this version, but the mechanism gives an off-registry actor a persistent import-time write primitive into every installer's tmp directory."
That is the whole problem with scanning for malice rather than for capability. A mutable main-branch URL in a personal GitHub account, with no pin, no hash and no signature, fetched at import time — the bytes on disk today are not the bytes an advisory can bound. CloudSEK reports that the second stage retrieved through this arm is a 64 MB Node.js stealer (movinlike) targeting Discord clients, browser data and Telegram tdata, exfiltrating to a webhook that was live when they wrote. We have not independently reproduced the payload chain and do not recommend anyone try; the registry-state and advisory facts above are what we verified.
CloudSEK's other claim worth flagging carefully: they say the recovered Overlord RAT build — Jamf Threat Labs documented Overlord on 6 August 2026 in a fake-Zoom macOS campaign — contains the Solana-memo C2 resolver that Jamf described as present but disabled, here wired in as live literal strings. If that holds, it is a first observed instance of that channel being usable, and it arrives via an npm vector that Jamf's writeup explicitly left as "still under investigation." That is CloudSEK's analysis of a sample we do not have; treat it as vendor-reported rather than confirmed.
Why this is an AI-tooling problem, not just an npm problem
Three of the campaign's packages are ASCII-art and colour helpers — exactly the shape of dependency a code-generating assistant reaches for without a second thought, and exactly the shape a human reviewer skims past. The operator's cover packages are functional. The postinstall runs regardless.
We have now covered this same takedown-vs-dependency gap three times in five weeks from three different researchers: GHAPPIER's sixty-five repositories and twenty-two accounts, the MemTensor release-pipeline compromise, and now MALFEX. The common failure is not detection. In every case someone did detect something. The failure is that the unit of response is a package name, while the unit of attack is an operator with a dependency graph.
What to do
- Block all three unadvised names outright:
function-flag,function-color,cdn-img-fetch. Your SCA tool will not flag the first two — there is nothing to flag against. This has to go in a denylist, not a scanner rule. - Treat an advisory's named dependencies as in-scope by default. When a malware advisory names a companion package, check that package's registry status the same hour. MAL-2026-17216 named
cdn-img-fetchon 28 September; it was still installable and shipped two further versions before its own advisory landed on the 30th, and that advisory's affected range still stops at 1.0.1. - Make
postinstallan explicit allowlist.npm ci --ignore-scriptsin CI, and an inventory of every package in your tree that declares install-time scripts. Fourteen months of undetected execution is what the default buys you. - Hunt the artefacts, not the package name. CloudSEK publishes persistence indicators — a scheduled task named
\Maidenand anAutoIt3.exedropped under a vendor-shaped%LOCALAPPDATA%directory. Those survive a package rename; the package name does not. - Pin transitively, or accept that you have not pinned. The caret range the advisory called out is the mechanism by which a taken-down parent keeps delivering through a live child. The same gap-between-detection-and-revocation pattern showed up in credential handling two days ago, from an entirely different direction.
Sources:
- CloudSEK — "MALFEX: A malicious npm postinstall no advisory has caught for fourteen months" (Vikas Kundu, 30 September 2026; operator attribution, two delivery arms, Overlord and movinlike payload analysis, persistence indicators)
- OSV / Amazon Inspector — MAL-2026-17216, malicious code in
img-to-native(npm), published 28 September 2026 - OSV / Amazon Inspector — MAL-2026-17320, malicious code in
cdn-img-fetch(npm), published 30 September 2026; affected versions 1.0.0 and 1.0.1 - npm registry metadata —
function-flag,function-color,cdn-img-fetch,img-to-native(version lists, publish timestamps,postinstallscript and dependency declarations; queried 1 October 2026)