FUXA's Unauthenticated Project Data Disclosure Exposes Server-Side Scripts and Device Configurations
Description
Summary
The GET /api/project endpoint exposes sensitive project configuration data to guest-context requests even when secureEnabled is enabled.
Details
File: server/api/projects/index.js
prjApp.get("/api/project", secureFnc, function(req, res) {
const permission = checkGroupsFnc(req);
runtime.project.getProject(req.userId, permission).then(result => {
if (result) {
res.json(result);
}
});
});
The endpoint uses the secureFnc middleware, but this middleware calls verifyToken in server/api/jwt-helper.js which auto-generates a valid guest JWT when no token is provided (line 49-51):
if (!token) {
token = getGuestToken();
}
The guest token is signed with the server's secret and passes verification. The handler then calls getProject which returns the full project data. The _filterProjectPermission function (line 924 of server/runtime/project/index.js) filters some UI elements for non-admin users, but it does not remove scripts, devices, alarms, or other sensitive configuration data.
PoC
Environment
- FUXA v1.3.0-2773 (
frangoteam/fuxa:latest) secureEnabled: truewith a randomsecretCode
Retrieve full project data without authentication:
curl -s http://192.168.32.129:1881/api/project
{
"scripts": [
{
"id": "SCRIPT_ID",
"name": "calculate"
},
]
}
No authentication token, API key, or cookie was provided. The response includes:
- Server-side scripts: full source code, IDs, names, execution mode, and permission levels. This reveals internal automation logic and sensitive project structure information that could assist further attacks against the deployed system.
- Device configurations: and communication endpoint information may also be exposed depending on the deployed project configuration.
- HMI views: the full SVG content and layout of every operator screen, including variable bindings that map UI elements to device tags.
- Alarm definitions: alarm thresholds, conditions, and notification settings when configured.
Impact
The endpoint may expose sensitive project configuration data including script metadata, device connection information, HMI configuration, and alarm definitions. In industrial environments this information can assist further targeted attacks against the deployed system.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
The GET /api/project endpoint in FUXA prior to 1.3.1 exposes sensitive project config to unauthenticated attackers via auto-generated guest JWT.
Vulnerability
The GET /api/project endpoint in FUXA (prior to v1.3.1) uses a secureFnc middleware that calls verifyToken in server/api/jwt-helper.js. When no token is provided, a valid guest JWT is auto-generated (lines 49-51). The handler then returns full project data via getProject, and while _filterProjectPermission removes some UI elements, it does not filter scripts, devices, alarms, or other sensitive configuration. [1][2]
Exploitation
An attacker can send a simple HTTP GET request to /api/project without any authentication token, API key, or cookie. The server automatically creates a guest token that passes verification, and the response includes full server-side script source code, device configurations, HMI view SVGs with variable bindings, alarm definitions, and more. [1][2]
Impact
An unauthenticated attacker gains access to all project configuration data, including server-side scripts (source code, execution mode, permission levels), device communication endpoints, operator screen layouts, and alarm thresholds. This exposes internal automation logic and can assist further attacks against the system. [1][2]
Mitigation
The vulnerability is fixed in FUXA v1.3.1 [3]. Users should upgrade to v1.3.1 or later. No workarounds are provided; the fix likely involves proper authentication validation for the endpoint. [3]
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
fuxa-servernpm | >= 1.3.0, < 1.3.1 | 1.3.1 |
Affected products
2= 1.3.0+ 1 more
- (no CPE)range: = 1.3.0
- (no CPE)range: = v1.3.0-2773
Patches
178534da61a91Security fixes (#2260)
3 files changed · +7 −8
server/api/command/index.js+1 −1 modified@@ -78,7 +78,7 @@ module.exports = { if (res.statusCode === 403) { runtime.logger.error("api get getTagValue: Tocken Expired"); } else if (!authJwt.haveAdminPermission(permission) && !runtime.scriptsMgr.isAuthorisedByScriptName(req.query.sourceScriptName, permission)) { - res.status(400).json({error:"unauthorized_error", message: "Unauthorized!"}); + res.status(401).json({error:"unauthorized_error", message: "Unauthorized!"}); runtime.logger.error("api get getTagValue: Unauthorized"); } else { try {
server/integrations/node-red/index.js+4 −5 modified@@ -152,12 +152,11 @@ async function mountNodeRedIfInstalled({ app, server, settings, runtime, logger, }); }; - // Allow public dashboard UI and socket.io; require JWT or API key for admin/editor/flows when security is enabled + // Allow only dashboard routes as public; require JWT or API key for admin/editor/flows when security is enabled const allowDashboard = (req, res, next) => { - const url = req.originalUrl || req.url || req.path; - - // Public dashboard UI and its HTTP APIs (served from httpNodeRoot/ui.path) - if (url.includes('/dashboard') || url.includes('/socket.io')) return next(); + // Public dashboard UI and its HTTP APIs (served from httpNodeRoot/ui.path). + // baseUrl comes from Express mount point and is not affected by query/path tricks. + if (req.baseUrl === '/dashboard') return next(); if (!settings.secureEnabled || settings.nodeRedAuthMode === 'legacy-open') { return next();
server/runtime/scripts/index.js+2 −2 modified@@ -106,7 +106,7 @@ function ScriptsManager(_runtime) { this.isAuthorisedByScriptName = function (scriptName, permission) { const script = scriptModule.getScriptByName(scriptName); if (!script) { - return true; + return false; } return this.isAuthorised(script, permission); } @@ -366,4 +366,4 @@ const ScriptSchedulingMode = { const SchedulerType = { weekly: 0, date: 1, -} \ No newline at end of file +}
Vulnerability mechanics
Root cause
"The `secureFnc` middleware auto-generates a valid guest JWT when no token is provided, and the `getProject` handler does not filter out sensitive configuration data (scripts, devices, HMI views, alarms) for guest-context requests."
Attack vector
An attacker sends an unauthenticated GET request to `/api/project` with no JWT token, API key, or cookie [ref_id=1][ref_id=2]. The `secureFnc` middleware calls `verifyToken` in `server/api/jwt-helper.js`, which auto-generates a signed guest JWT when no token is present (lines 49-51) [ref_id=1][ref_id=2]. The guest token passes verification, and the handler returns the full project data. The `_filterProjectPermission` function removes some UI elements for non-admin users but does not strip scripts, devices, alarms, or other sensitive configuration [ref_id=1][ref_id=2]. The response exposes server-side script source code, device connection information, full HMI SVG views with variable bindings, and alarm definitions [ref_id=1][ref_id=2].
Affected code
The vulnerable endpoint is `GET /api/project` in `server/api/projects/index.js`, which uses `secureFnc` middleware [ref_id=1][ref_id=2]. The `verifyToken` function in `server/api/jwt-helper.js` auto-generates a guest JWT when no token is provided (lines 49-51) [ref_id=1][ref_id=2]. The `_filterProjectPermission` function in `server/runtime/project/index.js` (line 924) fails to remove scripts, devices, alarms, or other sensitive configuration for non-admin users [ref_id=1][ref_id=2].
What the fix does
The patch [patch_id=2799074] addresses multiple authentication gaps. In `server/integrations/node-red/index.js`, the dashboard route check was changed from a substring match on `req.originalUrl` (which could be tricked) to an exact match on `req.baseUrl`, preventing path-based bypasses. In `server/runtime/scripts/index.js`, `isAuthorisedByScriptName` now returns `false` (instead of `true`) when a script name is not found, closing an authorization bypass. The command API endpoint in `server/api/command/index.js` now returns HTTP 401 instead of 400 for unauthorized tag value requests, though this is a status-code correction rather than a direct fix for the project data disclosure. The advisory [ref_id=1] notes the fix is included in FUXA v1.3.1.
Preconditions
- configThe server must have secureEnabled set to true (the bug exists regardless, but the impact is most relevant when security is intended to be enforced).
- networkNetwork access to the FUXA server's HTTP port (default 1881).
- inputNo authentication token, API key, or cookie is required; the request is sent without any credentials.
Reproduction
**Environment**: FUXA v1.3.0-2773 with `secureEnabled: true` and a random `secretCode`. Send an unauthenticated GET request: `curl -s http://<target>:1881/api/project`. The response returns the full project JSON including scripts, device configurations, HMI views, and alarm definitions [ref_id=1][ref_id=2].
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.