Skip to content

Scheduler API missing admin check enables operator-to-admin escalation via scheduled device actions

Moderate
unocelli published GHSA-8ghr-w65f-j3qr May 29, 2026

Software

frangoteam/FUXA

Affected versions

<= 1.3.1

Patched versions

>= 1.3.2

Description

Summary

An authorization issue in the Scheduler API allowed authenticated non-admin users to create or modify scheduled actions that should be restricted to administrators.

Details

The Scheduler API did not correctly enforce administrator permissions when processing scheduler modifications.

As a result, authenticated users with non-administrative roles could create or modify scheduled actions that execute privileged operations, including device value changes and server-side script execution.

The issue was fixed in version 1.3.2 by enforcing the appropriate permission checks for scheduler modifications.

Impact

An operator-level user in FUXA reaches the PLC-write and server-side-script-execution surface that the platform otherwise restricts to administrators. In a SCADA deployment those two privileges cover setpoint control and the automation scripting engine. Alice schedules a job that rewrites a pump's enable tag, opens a safety interlock, or runs a project script that walks the device tree. The scheduled-action model extends the attack: Alice does not need to keep a session open for the action to fire, and a repeating schedule re-applies her changes every cycle even if an admin reverts them manually.

CVSS 3.1: AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L (Medium, 6.3). CWE-862.

Recommended Fix

Add authJwt.haveAdminPermission(permission) to both POST /api/scheduler and DELETE /api/scheduler, matching every other write endpoint that reaches runtime.devices.setTagValue or runtime.scriptsMgr.runScript.

schedulerApp.post("/api/scheduler", secureFnc, function(req, res) {
    if (res.statusCode === 403) {
        runtime.logger.error("api post scheduler: Tocken Expired");
        return;
    }
    const permission = checkGroupsFnc(req);
    const isGuest = authJwt.isGuestUser(req.userId, req.userGroups);
    if (runtime.settings?.secureEnabled && (isGuest || !authJwt.haveAdminPermission(permission))) {
        res.status(401).json({error:"unauthorized_error", message: "Unauthorized!"});
        runtime.logger.error("api post scheduler: admin permission required");
        return;
    }
    // ... rest unchanged ...
});

Apply the same change to the delete handler at server/api/scheduler/index.js:102-112. As defense in depth, the scheduler service should also validate each deviceActions entry against the creator's stored groups before execution (e.g., reject onRunScript on any scheduler whose author is not an admin at execution time).


Found by aisafe.io

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
Low

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L

CVE ID

CVE-2026-47721

Weaknesses

Missing Authorization

The product does not perform an authorization check when an actor attempts to access a resource or perform an action. Learn more on MITRE.

Credits