Security researchers have disclosed a new software supply chain campaign dubbed MALFEX, and one of its confirmed components is a malicious npm package named imgdecode. Published to the npm registry on September 30, 2026 by the user malfexteste8, the package masquerades as an image decoding utility while concealing a shellcode loader inside a Windows native addon (a compiled .node binary module). As of the reporting, the package had been downloaded 979 times and was still live on the registry.
This is not a theoretical risk. Every download represents a developer workstation, a CI/CD build agent, or a production container that may have executed attacker-controlled shellcode. Native addons are a particularly insidious delivery vehicle: they bypass the JavaScript-level static analysis most security tooling performs on npm packages, they execute with the full privileges of the Node.js process, and they blend into the legitimate node-gyp/prebuild-install ecosystem that thousands of trustworthy packages rely on.
If your organization builds Node.js applications — and statistically, it does — you need to answer three questions today: Did imgdecode enter our dependency tree? Did its install-time or runtime code execute? And can we prevent the next one?
Technical Analysis
What We Know About the Package
- Package name:
imgdecode(npm registry) - Published: September 30, 2026
- Publisher account:
malfexteste8 - Download count: 979 (at time of reporting)
- Status: Still available on npm at time of reporting — do not assume registry takedown has occurred
- Campaign attribution: MALFEX, a recently disclosed software supply chain attack campaign
- Payload delivery: Shellcode loader embedded in a Windows native addon (compiled
.nodemodule loaded via Node.js N-API/require()bindings)
How the Attack Works — Defender's View of the Kill Chain
The tradecraft here follows a pattern we've watched mature across npm supply chain incidents, with a meaningful escalation: the payload is native code, not obfuscated JavaScript.
-
Package publication and social proof. A benign-sounding utility package (
imgdecodeimplies image decoding — a plausible dependency for web apps, thumbnail services, or asset pipelines) is published under a throwaway maintainer account. Typosquatting-adjacent naming and dependency confusion are the typical vectors for initial inclusion in a victim'spackage.json, either directly or as a transitive dependency. -
Install-time execution. Malicious npm packages almost universally weaponize lifecycle scripts (
preinstall,install,postinstall) inpackage.json. These scripts run automatically duringnpm installwith the installing user's privileges — on developer laptops, on build agents, and inside containers. This is where the loader stages or activates the native addon. -
Native addon loading. The package ships a precompiled
.nodebinary (or compiles one at install time vianode-gyp). When the package isrequire()'d, Node.js loads this binary directly into thenode.exeprocess address space. There is no JavaScript to audit — the malicious logic exists only as compiled machine code. -
Shellcode execution. The native addon acts as a shellcode loader: it allocates executable memory (classic
VirtualAlloc→VirtualProtect→ execution flow, or thread-injection variants), writes embedded or downloaded shellcode, and executes it in-process. Because execution occurs inside the legitimate, often trustednode.exeprocess, it inherits that process's reputation with EDR and application allowlisting solutions. -
Post-exploitation. Shellcode loaders in supply chain campaigns typically deliver credential harvesters (browser stores, SSH keys, cloud CLI tokens,
.npmrcand.envfiles — all high-value on developer machines), second-stage C2 implants, or persistence mechanisms. Developer workstations are crown-jewel targets precisely because they hold the keys to source code, build signing, and production deployment.
Why Native Addons Defeat Common Controls
- Static analysis blind spot: Most npm security scanners (including default
npm auditand many SCA tools) analyze JavaScript. A compiled.nodebinary is opaque to them. - Process masquerading: Malicious activity executes as
node.exe, a process most EDR policies treat as developer-normal. - Legitimate ecosystem cover: Thousands of genuine packages (
sharp,bcrypt,sqlite3,canvas) ship native addons viaprebuild-installornode-gyp, so the presence of a.nodefile is not inherently anomalous. Detection must focus on behavior: who loads it, from where, and what the process does afterward.
Exploitation Status
- In-the-wild distribution: Confirmed — 979 downloads from the live npm registry.
- Active campaign: Yes — part of the MALFEX campaign, disclosed October 2026.
- CVE: None assigned (malicious package, not a vulnerability). No CISA KEV entry applies.
- Registry status: Still available at time of reporting — treat any environment that resolves npm packages as potentially exposed until takedown and cache propagation are confirmed.
Detection & Response
The detections below target the observable behaviors of this threat class: native addon loading from suspicious paths, Node.js processes exhibiting loader-like child process and command-line behavior, and lifecycle-script execution spawning unexpected binaries. These are tuned to be high-signal — the baseline rule is node.exe spawning shells or LOLBins, which is almost never legitimate outside of actively debugged build tooling.
Sigma Rules
---
title: Node.js Process Spawning Shell or LOLBin - Potential npm Supply Chain Payload
transactionId: 8f2c4a91-3b7d-4e5a-9c1f-2d6e8a0b4f71
id: 8f2c4a91-3b7d-4e5a-9c1f-2d6e8a0b4f71
status: experimental
description: Detects node.exe spawning command shells, script interpreters, or Windows LOLBins. Malicious npm packages such as MALFEX's 'imgdecode' execute shellcode loaders and staging commands from within the Node.js process during install lifecycle scripts or native addon execution. Rarely legitimate outside of interactive debugging.
references:
- https://thehackernews.com/2026/10/malfex-npm-package-imgdecode-hides.html
- https://attack.mitre.org/techniques/T1195/002/
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/10/03
tags:
- attack.supply_chain_compromise
- attack.t1195.002
- attack.execution
- attack.t1059
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\node.exe'
- '\npm.cmd'
- '\npx.cmd'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\rundll32.exe'
- '\regsvr32.exe'
- '\mshta.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\curl.exe'
- '\certutil.exe'
- '\bitsadmin.exe'
condition: selection_parent and selection_child
falsepositives:
- Legitimate build tooling invoking scripts during node-gyp compilation (correlate with node-gyp in command line)
- Developer debugging sessions
level: high
---
title: Native Node Addon Loaded From Suspicious Path
transactionId: 4d1e7b23-9a6c-4f82-b3d5-7e0c1a9f8254
id: 4d1e7b23-9a6c-4f82-b3d5-7e0c1a9f8254
status: experimental
description: Detects image load events where a .node native addon binary is loaded from user-writable or temporary locations instead of a standard node_modules tree. The MALFEX 'imgdecode' package stages a shellcode loader inside a compiled .node addon; staging it to temp paths is a common evasion pattern.
references:
- https://thehackernews.com/2026/10/malfex-npm-package-imgdecode-hides.html
- https://attack.mitre.org/techniques/T1195/002/
- https://attack.mitre.org/techniques/T1129/
author: Security Arsenal
date: 2026/10/03
tags:
- attack.supply_chain_compromise
- attack.t1195.002
- attack.execution
- attack.t1129
logsource:
category: image_load
product: windows
detection:
selection:
ImageLoaded|endswith: '.node'
filter_paths:
ImageLoaded|contains: '\node_modules\'
condition: selection and not filter_paths
falsepositives:
- Portable or self-contained Electron applications bundling addons outside node_modules
- Custom enterprise packaging of native modules
level: medium
---
title: npm Lifecycle Script Spawning Download or Execution Tooling
transactionId: b7a3f5c8-2e94-4d61-a8c2-5f0e7b3d9168
id: b7a3f5c8-2e94-4d61-a8c2-5f0e7b3d9168
status: experimental
description: Detects processes spawned under npm/node install chains that invoke download cradles, encoded commands, or direct binary execution. Malicious packages like 'imgdecode' abuse preinstall/postinstall lifecycle hooks to stage native loaders and retrieve second-stage payloads.
references:
- https://thehackernews.com/2026/10/malfex-npm-package-imgdecode-hides.html
- https://attack.mitre.org/techniques/T1195/002/
- https://attack.mitre.org/techniques/T1105/
author: Security Arsenal
date: 2026/10/03
tags:
- attack.supply_chain_compromise
- attack.t1195.002
- attack.command_and_control
- attack.t1105
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentCommandLine|contains:
- 'npm install'
- 'npm ci'
- 'node-gyp'
- 'prebuild-install'
- 'preinstall'
- 'postinstall'
selection_suspicious:
CommandLine|contains:
- 'Invoke-WebRequest'
- 'Invoke-Expression'
- 'IEX'
- 'FromBase64String'
- ' -enc '
- ' -e '
- 'DownloadString'
- 'VirtualAlloc'
- 'certutil -decode'
- 'curl.exe http'
condition: selection_parent and selection_suspicious
falsepositives:
- Legitimate packages downloading prebuilt binaries from official release endpoints (allowlist known-good hosts such as github.com release assets for approved packages)
level: high
KQL — Microsoft Sentinel / Defender
This query hunts for the core behavioral signature — Node.js or npm install chains spawning shells, LOLBins, or encoded/download cradles — plus file artifacts consistent with the imgdecode package landing on disk. Run it across developer workstations and build agents first; that is where supply chain malware concentrates.
let Lookback = 14d;
let SuspiciousChildren = dynamic([
"cmd.exe", "powershell.exe", "pwsh.exe", "rundll32.exe", "regsvr32.exe",
"mshta.exe", "wscript.exe", "cscript.exe", "curl.exe", "certutil.exe",
"bitsadmin.exe", "wmic.exe"
]);
let NodeProcesses = DeviceProcessEvents
| where Timestamp > ago(Lookback)
| where InitiatingProcessFileName in~ ("node.exe", "npm.cmd", "npx.cmd", "node")
or InitiatingProcessCommandLine has_any ("npm install", "npm ci", "node-gyp", "prebuild-install", "postinstall", "preinstall");
let SuspiciousExec = NodeProcesses
| where FileName in~ (SuspiciousChildren)
or ProcessCommandLine has_any ("FromBase64String", "Invoke-Expression", "IEX", "DownloadString", "VirtualAlloc", "certutil -decode", " -enc ")
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, SHA256, ReportId;
let ImgdecodeArtifacts = DeviceFileEvents
| where Timestamp > ago(Lookback)
| where FolderPath has_any ("imgdecode", "malfex")
or (FileName endswith ".node" and FolderPath !has "node_modules")
| project Timestamp, DeviceName, InitiatingProcessFileName, FolderPath, FileName, SHA256, ReportId;
union SuspiciousExec, ImgdecodeArtifacts
| order by Timestamp desc
If your environment ingests Sysmon or CEF logs into Sentinel instead of Defender tables, the same logic ports directly: filter SecurityEvent/CommonSecurityLog for node.exe as parent with the same child-process and command-line indicator sets.
Velociraptor VQL
Use this artifact for fleet-wide scoping: it enumerates running Node.js processes and their command lines, then sweeps common module installation paths for the imgdecode package directory and recently created native addon binaries outside standard trees. Deploy it as a hunt across your developer and build infrastructure.
-- MALFEX imgdecode supply chain scoping artifact
-- 1. Enumerate node/npm processes and command lines
LET procs = SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Name =~ 'node|npm|npx'
OR CommandLine =~ 'imgdecode|node-gyp|prebuild-install'
-- 2. Find imgdecode package directories and suspicious .node binaries
LET hits = SELECT FullPath, Size, Mtime, Btime
FROM glob(globs=[
'C:/Users/*/**/node_modules/imgdecode/**',
'C:/Program Files/**/node_modules/imgdecode/**',
'C:/**/node_modules/imgdecode/package.json',
'C:/Users/*/AppData/Local/Temp/**/*.node',
'C:/Windows/Temp/**/*.node',
'C:/ProgramData/**/*.node'
])
WHERE NOT FullPath =~ 'node_modules'
OR FullPath =~ 'imgdecode'
SELECT * FROM procs
UNION ALL
SELECT NULL AS Pid, NULL AS Ppid, 'FILE_HIT' AS Name,
FullPath AS CommandLine, NULL AS Exe, NULL AS Username,
Mtime AS CreateTime
FROM hits
Remediation & Scoping Script
Run this PowerShell script on developer workstations and build agents to determine exposure, remove the malicious package, and harden npm against lifecycle-script abuse. Adapt the search root for your environment's project locations.
# MALFEX 'imgdecode' exposure check and remediation - run as Administrator where possible
$ErrorActionPreference = 'SilentlyContinue'
$SearchRoots = @("$env:USERPROFILE\source", "$env:USERPROFILE\repos", "$env:USERPROFILE\projects", "C:\builds", "C:\agent\_work")
$ReportPath = "$env:TEMP\imgdecode_exposure_report.txt"
"MALFEX imgdecode exposure scan - $(Get-Date)" | Out-File $ReportPath
# 1. Search dependency manifests and lockfiles for the malicious package
foreach ($root in $SearchRoots) {
if (Test-Path $root) {
Get-ChildItem -Path $root -Recurse -Include 'package.json','package-lock.json','yarn.lock','pnpm-lock.yaml' -ErrorAction SilentlyContinue |
Select-String -Pattern 'imgdecode' -List |
ForEach-Object { "[EXPOSED] $($_.Path)" | Out-File $ReportPath -Append }
}
}
# 2. Detect installed package artifacts on disk
foreach ($root in $SearchRoots) {
if (Test-Path $root) {
Get-ChildItem -Path $root -Recurse -Directory -Filter 'imgdecode' -ErrorAction SilentlyContinue |
ForEach-Object { "[INSTALLED] $($_.FullName)" | Out-File $ReportPath -Append }
}
}
# 3. Check global npm installations and npm cache
npm ls -g imgdecode 2>$null | Out-File $ReportPath -Append
Get-ChildItem "$env:LOCALAPPDATA\npm-cache" -Recurse -Filter '*imgdecode*' -ErrorAction SilentlyContinue |
ForEach-Object { "[CACHE] $($_.FullName)" | Out-File $ReportPath -Append }
# 4. Flag stray native addons outside node_modules (loader staging indicator)
foreach ($p in @("$env:TEMP", "C:\Windows\Temp", "C:\ProgramData")) {
Get-ChildItem -Path $p -Recurse -Filter '*.node' -ErrorAction SilentlyContinue |
ForEach-Object { "[STRAY-ADDON] $($_.FullName) created $($_.CreationTime)" | Out-File $ReportPath -Append }
}
# 5. If exposed: remove package and force clean reinstall with scripts disabled
$exposed = Select-String -Path $ReportPath -Pattern '\[EXPOSED\]|\[INSTALLED\]' -Quiet
if ($exposed) {
"[!] EXPOSURE DETECTED - treating host as compromised, see IR steps below" | Out-File $ReportPath -Append
# In each affected project directory, run manually after credential rotation:
# npm uninstall imgdecode
# npm cache clean --force
# Remove-Item -Recurse -Force node_modules, package-lock.json
# npm install --ignore-scripts
}
# 6. Harden npm globally: disable lifecycle scripts by default (breaks this attack class)
npm config set ignore-scripts true --location=user
"[HARDENED] ignore-scripts=true set for user $($env:USERNAME)" | Out-File $ReportPath -Append
Get-Content $ReportPath
Note the deliberate design choice in step 5: the script reports and hardens but does not auto-remediate an exposed host. If imgdecode executed on a machine, uninstalling the package does nothing for the shellcode that already ran. That host is an IR case, not a cleanup task.
Remediation
1. Scope exposure immediately (today).
- Search all
package.json,package-lock.json,yarn.lock, andpnpm-lock.yamlfiles across source control and build systems forimgdecode. Check transitive dependencies — a lockfile grep is the reliable method, notpackage.jsonreview alone. - Query your artifact registry/proxy (Artifactory, Nexus, Verdaccio, GitHub Packages) for cached copies of
imgdecodeand purge them. Registry takedown does not clear internal caches. - Review CI/CD pipeline logs for builds that fetched the package after September 30, 2026.
2. Treat every execution as a compromise. Any host that ran npm install against a dependency tree containing imgdecode executed attacker shellcode with that user's privileges. Standard IR procedure applies:
- Isolate the host; capture memory and disk images before remediation if forensics capacity allows.
- Rotate every credential the user context could reach: browser-stored credentials, SSH private keys, cloud provider tokens (
~/.aws,~/.azure,gcloudcredentials),.npmrcauth tokens,.envfiles, and any CI secrets present on build agents. Assume exfiltration. - Hunt the host with the Sigma/KQL/VQL content above for loader follow-on activity: persistence, C2 egress from
node.exe, and credential-access artifacts.
3. Structural hardening against this attack class.
- Disable lifecycle scripts by default (
ignore-scripts=truein user and CI.npmrc), then explicitly allowlist the small set of packages that legitimately need them. This single control breaks the install-time execution stage of the majority of malicious npm packages. - Pin dependencies and enforce lockfile integrity in CI (
npm ciwith immutable lockfiles, hash verification). Block floating version ranges on security-critical build agents. - Route all npm traffic through an internal proxy/registry with malware screening (e.g., an SCA gateway that quarantines newly published packages for a cooling-off period —
imgdecodewas weaponized from day one; a 7-14 day embargo on brand-new packages from brand-new publishers would have blocked it entirely). - Audit native addon usage. Maintain an allowlist of packages permitted to ship or compile
.nodebinaries in your environment. Alert on anything new loading a native module — that is precisely the signal this campaign generates. - Apply least privilege to build agents. Build runners should hold short-lived, scoped credentials only. The blast radius of a malicious install script is defined by what the installing identity can reach.
4. Registry and ecosystem actions.
- Report and monitor npm's security advisory feed for the formal
imgdecodetakedown notice; until confirmed removed, treat the package as live and downloadable. - Add
imgdecodeand the publishermalfexteste8to internal blocklists at the proxy layer, and monitor for MALFEX campaign sibling packages — supply chain actors publish in batches, andimgdecodeis unlikely to be the only package.
There is no vendor patch for a malicious package — the fix is removal, credential rotation, and the structural controls above. The organizations that absorb supply chain hits with the least damage are the ones that made malicious package execution technically hard before the package ever shipped.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.