CVE-2026-65984 Overview
FUXA is a web-based Process Visualization (SCADA/HMI/Dashboard) platform used to build industrial control interfaces. CVE-2026-65984 is an insufficient session expiration flaw [CWE-613] in FUXA versions 1.3.2 and earlier. The POST /api/refresh endpoint in server/api/auth/index.js falls back to decoded.groups from the JWT when current user data is missing. The POST /api/heartbeat endpoint in server/api/index.js re-signs inbound JWT claims without validating the database record. Attackers holding a previously issued privileged refresh cookie or access token can continue minting privileged JWTs after account deletion, disablement, or role demotion. The issue is fixed in version 1.3.3.
Critical Impact
An attacker with a stolen privileged token retains full administrative access to user management, project manipulation, runtime configuration, and script execution — even after the account has been deleted or demoted.
Affected Products
- FUXA SCADA/HMI 1.3.2 and earlier
- FUXA reference: GitHub Security Advisory GHSA-rg7m-xwqc-mjw6
- Fixed in FUXA Release v1.3.3
Discovery Timeline
- 2026-08-18 - CVE-2026-65984 published to NVD
- 2026-08-19 - Last updated in NVD database
Technical Details for CVE-2026-65984
Vulnerability Analysis
The flaw is a session lifecycle weakness in FUXA's authentication layer. Two server endpoints trust JWT claims from the request instead of authoritatively validating the backing user record. POST /api/refresh mints a new access token using decoded.groups when the current user lookup returns no data or a zero group value. POST /api/heartbeat re-signs inbound JWT claims and reissues tokens without checking whether the user still exists or retains the encoded privileges. Together, these paths let an attacker rotate a stale privileged session indefinitely. Once a session survives revocation, the attacker can create backdoor accounts, modify runtime configuration, and execute scripts on the SCADA host.
Root Cause
The root cause is trust in self-attested JWT claims during refresh and heartbeat operations. The server should treat the database as the source of truth for group membership and account status. Instead, it accepts the token's own groups field as authoritative when the corresponding user record is unavailable, deleted, or disabled.
Attack Vector
An attacker who obtains a privileged refresh cookie or access token — through session theft, replay of a leaked credential store, or a former insider retaining a token — sends periodic POST /api/refresh or POST /api/heartbeat requests to the FUXA server. Each response contains a newly signed JWT that preserves the original privileged groups claim, extending the session past any administrative revocation event.
// Patch: client/src/app/_services/auth.service.ts
// Source: https://github.com/frangoteam/FUXA/commit/4fa47d0a2a856ed34f427f472fb4450f86e7749b
return false;
}
- setNewToken(token: string) {
+ setNewToken(token: string, userData?: Partial<UserProfile>) {
if (!this.currentUser) {
return;
}
+ if (userData) {
+ this.currentUser.username = userData.username ?? this.currentUser.username;
+ this.currentUser.fullname = userData.fullname ?? this.currentUser.fullname;
+ this.currentUser.groups = userData.groups ?? this.currentUser.groups;
+ this.currentUser.info = userData.info ?? this.currentUser.info;
+ if (this.currentUser.info) {
+ this.currentUser.infoRoles = JSON.parse(this.currentUser.info)?.roles;
+ } else {
+ this.currentUser.infoRoles = null;
+ }
+ }
this.currentUser.token = token;
this.saveUserToken(this.currentUser);
+ this.currentUser$.next(this.currentUser);
}
The patch changes setNewToken to accept authoritative userData from the server and rebind username, groups, and roles on every refresh. Combined with server-side changes, revoked accounts no longer receive fresh privileged tokens. See the GitHub Pull Request Discussion for the full server-side changes.
Detection Methods for CVE-2026-65984
Indicators of Compromise
- Successful POST /api/refresh or POST /api/heartbeat requests using tokens tied to user IDs that no longer exist in the FUXA users table.
- New privileged sessions created without a preceding POST /api/signin event from the same client IP.
- Repeated token rotation activity from a single source over long periods after an administrator has deleted or demoted a user.
Detection Strategies
- Correlate FUXA authentication logs against the users database to flag active sessions whose subject no longer maps to an enabled account.
- Alert on user management, project write, or script execution actions performed by user IDs that were recently deleted or had their group membership reduced.
- Baseline heartbeat and refresh cadence per session and flag sessions that persist beyond expected administrative lifecycles.
Monitoring Recommendations
- Forward FUXA reverse proxy access logs and application logs to a centralized log platform for retention and correlation.
- Monitor for creation of new administrative accounts, changes to roles or groups fields, and modifications to scripts or runtime configuration.
- Track outbound connections from the FUXA host that may indicate backdoor account abuse against connected PLCs or field devices.
How to Mitigate CVE-2026-65984
Immediate Actions Required
- Upgrade FUXA to version 1.3.3 or later, which validates the current database record before issuing refreshed tokens.
- Invalidate all existing JWTs and refresh cookies by rotating the FUXA JWT signing secret after upgrade.
- Force re-authentication for every user and audit administrative accounts and group memberships for unauthorized changes.
Patch Information
The fix is delivered in FUXA v1.3.3 via commit 4fa47d0. Server-side changes stop trusting decoded.groups and require the current user record to authorize refresh and heartbeat token issuance. Client-side changes bind authoritative user data returned from the server into the local session.
Workarounds
- Place FUXA behind an authenticating reverse proxy or VPN so that stolen tokens cannot be replayed from untrusted networks.
- Shorten JWT and refresh cookie lifetimes in the FUXA configuration to reduce the window a stale privileged token remains valid.
- Manually rotate the JWT signing secret after any administrative deletion, demotion, or account disablement until the upgrade is applied.
# Upgrade FUXA to the patched release
git fetch --tags
git checkout v1.3.3
npm install
npm run build
# Rotate the JWT signing secret to invalidate previously issued tokens
export JWT_SECRET="$(openssl rand -hex 64)"
# Restart the FUXA service to apply the new secret
systemctl restart fuxa
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

