On 5 October 2026, Checkmarx published its analysis of MALFEX, an npm malware campaign that CloudSEK had attributed to a single operator on 30 September. The operator has been publishing since August 2023, tied 12 packages to five accounts, and eight of them delivered Windows malware: the Overlord remote access trojan, a stealer called movinlike, or a downloader. While the takedowns were happening, a new package, imgdecode, moved the loader into a compiled Windows DLL that runs as soon as the module is loaded.
What's affected
Checkmarx lists eight malicious packages. Download figures are its counts as of 1 October, and Checkmarx notes they measure registry reach, not infections:
| Package | Role | How it runs |
|---|---|---|
function-flag | Downloader, 37,419 lifetime downloads | postinstall script |
function-color | Wrapper that installs function-flag | postinstall script |
tlxbnhd, tldriver, mxdriver | Overlord RAT loaders | install hooks |
cdn-img-fetch, img-to-native, native-runner | Stealer chain | on require, no install hook |
All eight together had 40,767 downloads. On 18 October, we checked the npm registry: the three RAT loaders are unpublished, and the other five are replaced by npm's 0.0.1-security placeholder. Each has an OSV malware record, for example MAL-2026-17648 for function-flag.
Then the follow-ups. SafeDep's 13 October analysis, reported by The Hacker News, covers imgdecode, published by the account malfexteste8, and two short-lived helper packages, imgbundle and runhelper, both now gone. The four imgdecode versions were published between 30 September and 11 October. From 1.0.1 on, a native Node addon fetches an encrypted file from a GitHub repository, decrypts it with AES-256-CBC, and injects it into a hidden dllhost.exe. Version 1.0.3 drops every dependency on other MALFEX packages. The DLL exits unless it is attached to an interactive Windows console, which keeps it quiet on CI runners and in most sandboxes.
When we checked the registry and OSV on 18 October, imgdecode 1.0.0 to 1.0.3 were still published and OSV returned no record for the package. Treat it as malicious regardless.
The movinlike stealer, per Checkmarx and SafeDep, goes after Discord tokens, Chromium browser data, Telegram sessions, crypto wallets and files such as .kdbx, .pem, .ppk and .env, and offers remote shell and screenshot commands. Both firms report that the payloads fail silently on macOS and Linux.
How to check if you're exposed
Search the full dependency tree and every lock file, because Checkmarx notes malicious versions can stay pinned after a takedown:
PKGS='function-flag|function-color|tlxbnhd|tldriver|mxdriver|cdn-img-fetch|img-to-native|native-runner|imgdecode|imgbundle|runhelper'
npm ls --all 2>/dev/null | grep -E "$PKGS"
grep -rnE "\"($PKGS)\"|/($PKGS)/-/" --include=package-lock.json --include=pnpm-lock.yaml --include=yarn.lock .
Also purge them from internal registries, proxies and build caches. A registry takedown does not reach your mirror.
On Windows developer machines, check the host artifacts the researchers published. In PowerShell:
Test-Path "$env:LOCALAPPDATA\ScopeSmart Technologies Inc"
Test-Path "$env:APPDATA\Microsoft\Windows\node_runtime_helper.exe"
Test-Path "$env:APPDATA\node.exe"
Get-ScheduledTask | Where-Object TaskName -in 'Maiden','MicrosoftEdgeUpdateService'
Get-CimInstance Win32_Process -Filter "Name='dllhost.exe'" |
ForEach-Object { $p = Get-Process -Id $_.ParentProcessId -ErrorAction SilentlyContinue; if ($p.Name -eq 'node') { $_ } }
A dllhost.exe whose parent is node.exe is the injection pattern SafeDep describes. Network indicators include 104.234.65.75 on ports 700 and 7007.
What to do now
- Block all eleven names at your registry proxy, including the wrappers. Checkmarx points out that blocking
function-flagalone does not stopfunction-colorfrom pulling it in. - Treat any Windows machine that installed or loaded one as compromised. Isolate it and, as SafeDep advises, capture memory before rebooting, because the loader runs shellcode in memory.
- Rotate from a clean machine. Browser-saved passwords and sessions, Discord tokens, Telegram sessions, cloud and SSH keys, and npm and GitHub tokens. Move crypto funds to new wallets if seed phrases were on the host.
- Don't rely on disabling install scripts alone. It blocks the postinstall packages but not the stealer chain or
imgdecode, which run onrequire. - Don't rely on advisories alone. Checkmarx found two live packages with no advisory at all, and
imgdecodehad none when we looked.
Why it matters
MALFEX is not sophisticated, and the operator even signs the work: the publisher accounts, the README and an AES key all contain the name. It still lasted three years, and Orca's summary of the research says function-flag had been malicious since July 2025. Low-profile packages with plausible names get installed and rarely get read.
The move from install scripts to code that runs on import, and then into a compiled addon, is the trend to plan for. Disabling install scripts is still worth doing, but it is one layer. You also need to know when a dependency ships a native binary it didn't ship before, and to compare what you install against malware feeds continuously rather than once.
Try it yourself
List every package in one of your Node projects that ships a compiled .node file:
find node_modules -name '*.node' -type f | sed 's|/build/.*||; s|/prebuilds/.*||' | sort -u
For each, ask whether you expected native code there. Then run the project's lock file through the free scan at https://gold.safeguard.sh/scan, which checks dependencies against known malicious packages in your browser.
Click through it at your own pace, or open it full screen.
Quick check
Does npm install with ignore-scripts protect you from imgdecode?
No. imgdecode runs its native loader when the module is required, not at install time.
Why did MALFEX payloads not affect Linux CI runners?
The payloads are Windows only, and imgdecode's DLL also exits unless it is attached to an interactive Windows console.
Is blocking function-flag enough?
No. function-color depends on function-flag and pulls it in, so block every package in the campaign, including wrappers.
Sources
- Checkmarx: MALFEX npm malware campaign, three payloads and an adversary that signs their work
- SafeDep: MALFEX moves its npm loader into a native Windows DLL
- The Hacker News: Eight malicious npm packages downloaded 40,767 times
- The Hacker News: MALFEX npm package imgdecode hides shellcode loader
- Orca Security: MALFEX delivers RAT and stealer
- OSV MAL-2026-17648: function-flag
- npm registry metadata for imgdecode