16 min to read
Node-RED Under Attack: Find, Lock Down and Hunt CVE-2026-58115
A practical guide to the CVSS 10 flaw turning unprotected flow editors into Linux bots
Node-RED is the friendly drag-and-drop tool that quietly runs a surprising amount of the world’s glue code: factory gateways, building automation, home labs, IoT dashboards and plenty of “temporary” integration scripts that became permanent. It is also, by design, a remote programming environment. Anyone who can reach an unprotected editor can wire an exec node to a trigger and run shell commands on the host.
That is exactly what attackers started doing at scale last week. On 30 October 2026, a VulnCheck honeypot caught an attacker exploiting CVE-2026-58115, a CVSS 10.0 missing-authentication flaw in Node-RED on Siemens SIMATIC IoT2050 Advanced devices, and using it to drop a Linux bot and, later, persistent web shells (VulnCheck). The CVE is formally assigned to the Siemens product, but the technique works against any Node-RED editor that is reachable without authentication, which is why this matters well beyond one industrial gateway.
This guide shows you how to find your Node-RED instances, lock them down properly and hunt for signs that someone has already deployed a flow on your behalf.
TL;DR / Key takeaways
- CVE-2026-58115 (CVSS 3.1 and 4.0: 10.0, CWE-306) lets an unauthenticated remote attacker “create malicious flows and execute arbitrary code on the underlying server with maximum privileges” on SIMATIC IoT2050 Advanced running Industrial OS with Node-RED, all versions before V4.3.4.1 (Siemens SSA-834709).
- Exploitation was first seen on 30 October 2026: a single
POST /flowsrequest deployed aninject→execflow that downloaded a bot into/dev/shm. Later payloads added HTTP-triggered web shells that survive reboots (VulnCheck).- It is not in CISA’s KEV catalog at the time of writing, but VulnCheck has added it to its own KEV list (Help Net Security).
- Any standalone Node-RED with
adminAuthdisabled is exposed to the same abuse. EnableadminAuth, keep port 1880 off the internet and review every flow for unexpectedexecnodes andhttp inendpoints.- Patching or adding a password does not remove a flow an attacker already deployed. Hunt first, then harden.
What happened (quick timeline)
| Date (2026) | Event |
|---|---|
| 11 Aug | Siemens publishes SSA-834709 for CVE-2026-58115 and releases Industrial OS V4.3.4.1 |
| ~12 Aug | CISA enrichment records no known exploitation but rates the bug automatable with total technical impact (Security Point Break) |
| 27 Oct | VulnCheck ships detection artifacts to its customers |
| 30 Oct | First exploitation caught on a VulnCheck canary |
| 30 Oct – 1 Nov | 16 exploitation events from the same source IP; second-stage payloads and web shells appear |
| 2 Nov | VulnCheck publishes its analysis |
| 3 Nov | Wider coverage; still not in CISA KEV |
Sources: Siemens, VulnCheck, Help Net Security.
How the attack works (conceptually)
There is no memory corruption or clever bypass here. The problem is a missing lock on a very powerful door.
Node-RED’s editor talks to the runtime through an Admin HTTP API. One of its endpoints, POST /flows, replaces the running set of flows. If the admin API isn’t protected by adminAuth, anyone who can reach it can deploy whatever flow they like. Node-RED’s own documentation tells you to uncomment the adminAuth block in the settings file to enable it (Node-RED docs), and Siemens’ fixed firmware “enforces authentication on the web interface” (SecurityOnline).
According to VulnCheck, the observed attack went like this:
- One request. The attacker “sent one
POST /flowsfrom curl/8.5.0” containing a flow with aninjectnode set to fire once, one second after deploy, wired to anexecnode. - Obfuscated command. The
execnode ranecho <base64> | base64 -d | sh. VulnCheck notes the base64 layering means “a naive filter looking for wget or curl in the request body would not see them.” - Bot download. The decoded script fetched
bot-linux-amd64withwgetorcurl, saved it as/dev/shm/.b, made it executable and launched it detached withsetsidornohup. VulnCheck did not analyse the binary, so its function (miner, DDoS bot, reverse shell) is unknown. - Persistence via web shell. Later payloads deployed an
http inendpoint (for example/cmd, or a random path) wired through a function node to anexecnode, so commands could be passed in an HTTP request. As VulnCheck puts it, “This backdoor survives even if a memory-backed implant is lost on reboot”, because the flow itself is saved by Node-RED.
The source IP also hit eight other CVEs (Apache Solr, Gitea, MLflow, Traefik, Joomla and others), which VulnCheck reads as “opportunistic mass scanning.” In other words, you don’t need to be an interesting target. You only need to be reachable.
Am I affected?
You should treat yourself as exposed if any of these are true:
- You run SIMATIC IoT2050 Advanced (6ES7647-0BA00-1YA2) with Industrial OS before V4.3.4.1 and Node-RED installed.
- You run any Node-RED instance (Docker, Raspberry Pi, VM, bundled in a vendor product) where
adminAuthis not configured and the editor port (1880 by default) is reachable from an untrusted network. - You use a product that embeds Node-RED. VulnCheck notes Emerson documentation mentions Node-RED use but says it has not validated whether those products are affected. Ask your vendors.
Exposure figures are still emerging. SecurityOnline cites “more than 20,000” internet-exposed Node-RED interfaces, but does not name the scan source, so treat that number as indicative only.
Step 1: Inventory your Node-RED instances
Start with what you own. On a network you are authorised to scan, look for the default port and the editor’s tell-tale responses:
~|#| Find listeners on the default Node~|-|RED port in your own ranges
nmap ~|-|p 1880 ~|-|~|-|open ~|-|sV 10.0.0.0/16 ~|-|oG node~|-|red~|-|candidates.txt
~|#| On Linux hosts: is a Node~|-|RED process running, and who owns it?
ps ~|-|eo user,pid,args | grep ~|-|i "[n]ode~|-|red"
ss ~|-|ltnp | grep ':1880'
~|#| On Docker hosts
docker ps ~|-|~|-|format '{{.Names}}\t{{.Image}}\t{{.Ports}}' | grep ~|-|i node~|-|red
Don’t forget the less obvious places: vendor gateways on the plant floor, contractor-installed Raspberry Pis, and cloud VMs a developer spun up for “a quick demo”. Also check your external attack surface (Shodan/Censys exports, your own EASM tool) for anything answering on 1880.
Step 2: Check whether the admin API is open (safely)
For each instance you own, an unauthenticated read request tells you everything you need without changing anything:
~|#| Expect HTTP 401 if adminAuth is enabled. HTTP 200 with JSON ~|=| wide open.
curl ~|-|s ~|-|o /dev/null ~|-|w '%{http_code}\n' http://~|<|host>:1880/flows
~|#| Shows the active authentication scheme; an empty {} means no adminAuth
curl ~|-|s http://~|<|host>:1880/auth/login
Never send a POST /flows to test. That is the exploit, and on a production controller it would replace the running logic.
Step 3: Hunt for malicious flows and payloads
An attacker’s flow lives in Node-RED’s flow file (by default under the user directory, typically ~/.node-red/flows.json or flows_<hostname>.json). Review it for exec nodes and http in endpoints that nobody on your team created:
~|#| List every exec node and its command
jq ~|-|r '.[] | select(.type~|=|~|=|"exec") | [.id, .name, .command] | @tsv' ~/.node~|-|red/flows*.json
~|#| List every HTTP endpoint the runtime exposes
jq ~|-|r '.[] | select(.type~|=|~|=|"http in") | [.id, .method, .url] | @tsv' ~/.node~|-|red/flows*.json
~|#| Quick grep for the observed obfuscation pattern and payload paths
grep ~|-|El 'base64 ~|-|d \| sh|/dev/shm/\.b|/tmp/\.kworker|/tmp/\.s' ~/.node~|-|red/flows*.json
Then check the host itself for the artifacts VulnCheck published:
ls ~|-|la /dev/shm/.b /tmp/.s /tmp/.kworker 2>/dev/null
ps ~|-|eo pid,ppid,user,args | grep ~|-|E '\.b$|\.kworker|bot~|-|linux' | grep ~|-|v grep
Indicators published by VulnCheck
| Type | Value | Notes |
|---|---|---|
| IP | 4.201.105[.]116 |
Attack source (AS8075) |
| IP / URL | hxxp://85.215.73[.]250:8080/bot-linux-amd64 |
Bot payload |
| URL | hxxp://85.215.73[.]250:8080/wget.sh |
Second dropper |
| IP / URL | hxxp://45.194.90[.]57:38472/.sys_update |
Third payload, saved as /tmp/.kworker |
| Files | /dev/shm/.b, /tmp/.s, /tmp/.kworker |
Dropped on host |
| HTTP | POST /flows from external IPs |
Seen with curl, python-requests, Python-urllib and browser user agents |
No file hashes have been published. The source IP is on a large cloud provider and was likely a rented or compromised VM, so block it but don’t rely on it.
Detection logic
1. Turn on Node-RED audit logging. Set audit: true under logging.console in settings.js. Node-RED will then log Admin API access with the endpoint, IP address and timestamp, plus the user when adminAuth is on (Node-RED logging docs). A deploy looks like this:
[audit] {"event":"flows.set","type":"full","version":"v2","level":98,"user":{"username":"admin","permissions":"write"},"path":"/flows","ip":"127.0.0.1","timestamp":1489070062519}
Alert on any flows.set event from an IP outside your engineering subnet, or with no user field at all.
2. Web proxy / reverse proxy logs (Splunk). Flag deploys to the admin API from the outside:
index~|=|proxy OR index~|=|web (uri_path~|=|"/flows" OR uri_path~|=|"*/flows") http_method~|=|POST
| where NOT cidrmatch("10.0.0.0/8", src_ip) AND NOT cidrmatch("192.168.0.0/16", src_ip)
| stats count min(_time) as first max(_time) as last values(http_user_agent) by src_ip, dest, dest_port
3. Process lineage (Sigma). Node-RED’s exec node spawns shell commands as children of the Node.js process. A shell decoding base64, or a download into /dev/shm, under node is a strong signal:
title: Node~|-|RED Spawning Encoded Shell or Download to Memory~|-|Backed Path
status: experimental
description: Detects shell commands launched by a Node.js (Node~|-|RED) process that decode base64 into sh or fetch files into /dev/shm or hidden /tmp files, as seen in CVE~|-|2026~|-|58115 exploitation.
references:
~|-| https://www.vulncheck.com/blog/exploitation~|-|targeting~|-|node~|-|red
logsource:
product: linux
category: process_creation
detection:
parent:
ParentImage|endswith:
~|-| '/node'
~|-| '/nodejs'
shell_decode:
CommandLine|contains|all:
~|-| 'base64 ~|-|d'
~|-| 'sh'
dropper:
CommandLine|contains:
~|-| '/dev/shm/.'
~|-| '/tmp/.kworker'
~|-| 'bot~|-|linux~|-|amd64'
~|-| '.sys_update'
condition: parent and (shell_decode or dropper)
falsepositives:
~|-| Legitimate flows that run encoded maintenance scripts (rare; review and allowlist)
level: high
tags:
~|-| attack.execution
~|-| attack.t1059.004
~|-| attack.initial_access
~|-| attack.t1190
4. Microsoft Defender for Endpoint on Linux (KQL). The same idea for teams on Defender:
DeviceProcessEvents
| where Timestamp > ago(14d)
| where InitiatingProcessFileName in~ ("node", "nodejs")
| where ProcessCommandLine has_any ("base64 ~|-|d", "/dev/shm/.", "/tmp/.kworker", "bot~|-|linux~|-|amd64", ".sys_update")
| project Timestamp, DeviceName, AccountName, InitiatingProcessCommandLine, ProcessCommandLine
| order by Timestamp desc
5. Network. Alert on outbound connections from Node-RED hosts to 85.215.73[.]250:8080 or 45.194.90[.]57:38472, and more generally on IoT/OT gateways making outbound HTTP requests to raw IP addresses on high ports. Most gateways should only talk to a handful of known systems.
Step 4: Lock it down
Patch the Siemens devices. Update SIMATIC IoT2050 Advanced to Industrial OS V4.3.4.1 or later (Siemens download). If you can’t, Siemens’ own workarounds are to uninstall Node-RED or harden the installation per the Node-RED user guide.
Enable adminAuth everywhere. Generate a bcrypt hash with node-red admin hash-pw (Node-RED 1.1.0+), then add it to settings.js:
adminAuth: {
type: "credentials",
users: [
{ username: "ops~|-|admin", password: "~|<|bcrypt~|-|hash>", permissions: "*" },
{ username: "viewer", password: "~|<|bcrypt~|-|hash>", permissions: "read" }
]
},
sessionExpiryTime: 28800, // 8 hours instead of the 7~|-|day default
logging: {
console: { level: "info", metrics: false, audit: true }
},
Give most people read permissions and keep * for the few engineers who deploy. Use type: "strategy" with your identity provider (OAuth/OpenID) if you want SSO and MFA in front of the editor.
Protect the HTTP endpoints too. adminAuth only protects the editor and Admin API. Flows that expose http in endpoints are protected separately with httpNodeAuth, and static content with httpStaticAuth (Node-RED docs).
Add TLS and take it off the internet. Configure the https option or put Node-RED behind a reverse proxy with TLS and MFA. Don’t expose port 1880 publicly: reach it through a VPN or jump host, and segment OT gateways so they can’t initiate arbitrary outbound connections.
Run with least privilege. Siemens notes the flaw gives code execution “with maximum privileges.” Run Node-RED as a dedicated unprivileged user (or in a container without --privileged), and consider removing the exec node from instances that don’t need it.
Step 5: If you find a malicious flow
- Isolate the host from the network before you touch anything, especially on OT networks where the device may control physical processes.
- Preserve evidence: copy the flow file,
settings.js, Node-RED logs and a list of running processes./dev/shmis RAM-backed, so capture it before rebooting. - Remove the rogue nodes and kill dropped processes, but assume the attacker had full control of the host. On anything critical, rebuild from a known-good image.
- Rotate secrets stored in Node-RED credentials (MQTT, database, cloud API keys) and anything else the host could read.
- Check neighbours. A compromised gateway is a foothold inside a network that is often poorly monitored.
Prioritised checklist
Immediately (today)
- Find every Node-RED instance you own, including inside vendor products and containers.
- Check each one with
GET /flows; anything returning 200 without credentials is critical. - Block external access to port 1880 at the firewall.
- Review flows for unknown
execandhttp innodes; search hosts for the published file paths and IPs.
This week
- Update SIMATIC IoT2050 Advanced to V4.3.4.1 or later.
- Enable
adminAuth,httpNodeAuthand audit logging on all instances; ship logs to your SIEM. - Deploy the Sigma/KQL logic above and an outbound-connection alert for gateway hosts.
- Ask OT and IoT vendors whether their products embed Node-RED and how it is secured.
Longer term
- Put engineering tools behind SSO, MFA and a VPN or jump host by default.
- Segment OT/IoT networks and restrict egress to known destinations.
- Track VulnCheck KEV as well as CISA KEV; this bug was exploited months after disclosure, before it reached CISA’s list.
OffensioX perspective
CVE-2026-58115 is a reminder that the most dangerous “vulnerabilities” are often features left switched on in the wrong place. Node-RED is meant to run code; the failure is shipping or deploying it with the front door open. The exploit took one HTTP request, and the attacker didn’t even bother to target anyone in particular. They added Node-RED to a scanner that already tried Solr, Gitea and MLflow. We see the same pattern on assessments in Pakistan and the wider region: dashboards, automation tools and admin panels set up by integrators, never added to the asset register, and left on a public IP long after the project ended. Note too that the CVE sat at “no known exploitation” for over two months before someone weaponised it, so a quiet advisory is not a reason to wait. OffensioX offers penetration testing and attack surface assessments that find exactly these forgotten interfaces, across IT and OT, before a scanner does.
References
- Siemens ProductCERT: SSA-834709 – Missing Authentication Vulnerability in Node-RED on SIMATIC IoT2050 Advanced with Industrial OS
- Siemens: SIMATIC IoT2050 Industrial OS download
- VulnCheck: Exploitation Targeting Node-RED, a Tool Embedded in ICS Products
- Help Net Security: Attackers exploit critical Node-RED flaw to deploy Linux bot and backdoors (CVE-2026-58115)
- SecurityOnline: Node-RED Remote Code Execution Flaw CVE-2026-58115 with 10.0 CVSS Exploited in the Wild
- Security Point Break: Node-RED Flaw in Siemens IoT2050 Exploited (CVE-2026-58115)
- Node-RED: Securing Node-RED
- Node-RED: Logging (audit events)
- Node-RED Admin API: GET /auth/login