FUXA has SQL Injection in its TDengine DAQ connector via backslash bypass of escapeTdString
Description
Summary
The TDengine DAQ storage connector's escapeTdString at server/runtime/storage/tdengine/index.js:10 doubles single quotes but does not escape backslashes. TDengine's SQL parser treats \' as a literal single quote inside a string, so a tag id of the form x\' OR 1=1-- escapes the first single quote, lets the doubled quote close the string, and appends an injected clause that runs on the TDengine server. An attacker (Alice) sends the crafted sids value through GET /api/daq or the Socket.IO DAQ_QUERY event and reads every row in fuxa.meters, which holds the historical tag values of every PLC the FUXA instance records.
Details
The TDengine DAQ storage connector did not correctly sanitize user-controlled values before including them in SQL queries.
A specially crafted tag identifier could bypass the intended escaping logic and alter the query executed against the TDengine database.
This could allow unauthorized access to historical DAQ data stored in TDengine, including recorded tag values and related metadata.
The issue has been fixed in version 1.3.2 by improving input escaping in the TDengine connector.
Impact
An attacker with network access to a FUXA instance configured with TDengine as the DAQ backend reads the entire historical tag-value archive: every PLC tag the instance has recorded, plus the associated device ids and device names. Turning on authentication does not close the gap: the Socket.IO DAQ_QUERY handler has no authorization check, and /api/daq accepts guest-level requests. No login is needed in the default configuration.
CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N (Medium, 5.3). CWE-89. --- A fix is available at https://github.com/frangoteam/FUXA/releases/tag/v1.3.2.
--- *Found by aisafe.io*
Affected products
2- Range: <1.3.2
Patches
2629976f99958fix: keep Node-RED initialization compatible with plugin runtime
6 files changed · +327 −10
client/dist/index.html+1 −1 modified@@ -86,6 +86,6 @@ </div> </div> </app-root> -<script src="runtime.9136a61a9b98f987.js" type="module"></script><script src="polyfills.d7de05f9af2fb559.js" type="module"></script><script src="scripts.d9e6ee984bf6f3b7.js" defer></script><script src="main.3ce4b62c8690ee22.js" type="module"></script></body> +<script src="runtime.9136a61a9b98f987.js" type="module"></script><script src="polyfills.d7de05f9af2fb559.js" type="module"></script><script src="scripts.d9e6ee984bf6f3b7.js" defer></script><script src="main.5d9400ce5741688f.js" type="module"></script></body> </html>
client/dist/main.5d9400ce5741688f.js+1 −1 renamedclient/package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "fuxa", - "version": "1.3.2-2798", + "version": "1.3.2-2799", "keywords": [], "author": "frangoteam <info@frangoteam.org>", "description": "Web-based Process Visualization (SCADA/HMI/Dashboard) software",
server/package.json+2 −1 modified@@ -1,6 +1,6 @@ { "name": "fuxa-server", - "version": "1.3.2-2798", + "version": "1.3.2-2799", "description": "Web-based Process Visualization (SCADA/HMI/Dashboard) software", "main": "main.js", "scripts": { @@ -42,6 +42,7 @@ "nopt": "5.0.0", "pdfmake": "0.2.5", "pg": "^8.18.0", + "serialport": "12.0.0", "socket.io": "4.8.1", "sqlite3": "5.1.5", "swagger-ui-express": "^5.0.1",
server/package-lock.json+318 −2 modified@@ -1,12 +1,12 @@ { "name": "fuxa-server", - "version": "1.3.1-2789", + "version": "1.3.2-2798", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fuxa-server", - "version": "1.3.1-2789", + "version": "1.3.2-2798", "license": "MIT", "dependencies": { "@influxdata/influxdb-client": "1.25.0", @@ -36,6 +36,7 @@ "nopt": "5.0.0", "pdfmake": "0.2.5", "pg": "^8.18.0", + "serialport": "12.0.0", "socket.io": "4.8.1", "sqlite3": "5.1.5", "swagger-ui-express": "^5.0.1", @@ -1318,6 +1319,258 @@ "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", "hasInstallScript": true }, + "node_modules/@serialport/binding-mock": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", + "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", + "dependencies": { + "@serialport/bindings-interface": "^1.2.1", + "debug": "^4.3.3" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@serialport/binding-mock/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@serialport/binding-mock/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/@serialport/bindings-cpp": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz", + "integrity": "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==", + "hasInstallScript": true, + "dependencies": { + "@serialport/bindings-interface": "1.2.2", + "@serialport/parser-readline": "11.0.0", + "debug": "4.3.4", + "node-addon-api": "7.0.0", + "node-gyp-build": "4.6.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz", + "integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz", + "integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==", + "dependencies": { + "@serialport/parser-delimiter": "11.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@serialport/bindings-interface": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz", + "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==", + "engines": { + "node": "^12.22 || ^14.13 || >=16" + } + }, + "node_modules/@serialport/parser-byte-length": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz", + "integrity": "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-cctalk": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz", + "integrity": "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-delimiter": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz", + "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-inter-byte-timeout": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz", + "integrity": "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-packet-length": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz", + "integrity": "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==", + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@serialport/parser-readline": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz", + "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==", + "dependencies": { + "@serialport/parser-delimiter": "12.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-ready": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz", + "integrity": "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-regex": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz", + "integrity": "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-slip-encoder": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz", + "integrity": "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-spacepacket": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz", + "integrity": "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/stream": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz", + "integrity": "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==", + "dependencies": { + "@serialport/bindings-interface": "1.2.2", + "debug": "4.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/stream/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@serialport/stream/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/@sindresorhus/is": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", @@ -5010,6 +5263,11 @@ "node": ">=16" } }, + "node_modules/node-addon-api": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", + "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==" + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://mirrors.cloud.tencent.com/npm/node-fetch/-/node-fetch-2.7.0.tgz", @@ -5053,6 +5311,16 @@ "node": ">= 10.12.0" } }, + "node_modules/node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-gyp/node_modules/are-we-there-yet": { "version": "3.0.1", "resolved": "https://mirrors.cloud.tencent.com/npm/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", @@ -6160,6 +6428,54 @@ "randombytes": "^2.1.0" } }, + "node_modules/serialport": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-12.0.0.tgz", + "integrity": "sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==", + "dependencies": { + "@serialport/binding-mock": "10.2.2", + "@serialport/bindings-cpp": "12.0.1", + "@serialport/parser-byte-length": "12.0.0", + "@serialport/parser-cctalk": "12.0.0", + "@serialport/parser-delimiter": "12.0.0", + "@serialport/parser-inter-byte-timeout": "12.0.0", + "@serialport/parser-packet-length": "12.0.0", + "@serialport/parser-readline": "12.0.0", + "@serialport/parser-ready": "12.0.0", + "@serialport/parser-regex": "12.0.0", + "@serialport/parser-slip-encoder": "12.0.0", + "@serialport/parser-spacepacket": "12.0.0", + "@serialport/stream": "12.0.0", + "debug": "4.3.4" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/serialport/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/serialport/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
server/runtime/plugins/index.js+4 −4 modified@@ -158,7 +158,7 @@ async function addPlugin(plugin, options) { normalized.pkg = current.pkg; } - if (normalized.module && normalized.type) { + if (normalized.group !== PluginGroupType.service && normalized.module && normalized.type) { await device.loadPlugin(normalized.type, normalized.module); } plugins[normalized.name] = normalized; @@ -291,12 +291,12 @@ function _normalizeAddPluginOptions(options) { function createDefaultPlugins() { const registry = {}; registry['node-opcua'] = new Plugin('node-opcua', './opcua', 'OPCUA', '2.149.0', PluginGroupType.connectionDevice, true); - registry['modbus-serial'] = new Plugin('modbus-serial', './modbus', 'Modbus', '8.0.9', PluginGroupType.connectionDevice, true); + registry['modbus-serial'] = new Plugin('modbus-serial', './modbus', 'Modbus', '8.0.19', PluginGroupType.connectionDevice, true); registry['node-bacnet'] = new Plugin('node-bacnet', './bacnet', 'BACnet', '0.2.4', PluginGroupType.connectionDevice, true); - registry['node-snap7'] = new Plugin('node-snap7', './s7', 'SiemensS7', '1.0.7', PluginGroupType.connectionDevice, true); + registry['node-snap7'] = new Plugin('node-snap7', './s7', 'SiemensS7', '1.0.9', PluginGroupType.connectionDevice, true); registry['ads-client'] = new Plugin('ads-client', './adsclient', 'ADSclient', '2.1.0', PluginGroupType.connectionDevice, true); registry['nodepccc'] = new Plugin('nodepccc', './ethernetip', 'EthernetIP', '0.1.17', PluginGroupType.connectionDevice, true); - registry['odbc'] = new Plugin('odbc', './odbc', 'ODBC', '2.4.8', PluginGroupType.connectionDatabase, true); + registry['odbc'] = new Plugin('odbc', './odbc', 'ODBC', '2.4.9', PluginGroupType.connectionDatabase, true); registry['chart.js'] = new Plugin('chart.js', './chartjs', 'Chart', '2.9.4', PluginGroupType.chartReport, true); registry['chartjs-node-canvas'] = new Plugin('chartjs-node-canvas', 'chartjs-canvas', 'Chart', '3.2.0', PluginGroupType.chartReport, true); registry['onoff'] = new Plugin('onoff', './gpio', 'GPIO', '6.0.3', PluginGroupType.connectionDevice, true);
e16b7a8818c4Build for release 1.3.2
6 files changed · +18 −5
client/dist/index.html+1 −1 modified@@ -86,6 +86,6 @@ </div> </div> </app-root> -<script src="runtime.9136a61a9b98f987.js" type="module"></script><script src="polyfills.d7de05f9af2fb559.js" type="module"></script><script src="scripts.d9e6ee984bf6f3b7.js" defer></script><script src="main.e774d930909a7512.js" type="module"></script></body> +<script src="runtime.9136a61a9b98f987.js" type="module"></script><script src="polyfills.d7de05f9af2fb559.js" type="module"></script><script src="scripts.d9e6ee984bf6f3b7.js" defer></script><script src="main.6b9fca5ddf0b0488.js" type="module"></script></body> </html>
client/dist/main.6b9fca5ddf0b0488.js+1 −1 renamedclient/package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "fuxa", - "version": "1.3.2-2826", + "version": "1.3.2-2827", "keywords": [], "author": "frangoteam <info@frangoteam.org>", "description": "Web-based Process Visualization (SCADA/HMI/Dashboard) software",
client/proxy.conf.json+13 −0 modified@@ -1,4 +1,17 @@ { + "/api": { + "target": "http://127.0.0.1:1881", + "secure": false, + "logLevel": "debug", + "changeOrigin": true + }, + "/socket.io": { + "target": "http://127.0.0.1:1881", + "secure": false, + "logLevel": "debug", + "changeOrigin": true, + "ws": true + }, "/resources": { "target": "http://127.0.0.1:1881", "secure": false,
.github/workflows/docker_release.yml+1 −1 modified@@ -2,7 +2,7 @@ name: Build and Publish DHI release env: app: fuxa - version: 1.3.1 + version: 1.3.2 # for available platforms see output of a previous run - # ie the "Setup Docker BuildX" / "Inspect Builder" section # has eg "node_platforms": "linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6"
server/package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "fuxa-server", - "version": "1.3.2-2826", + "version": "1.3.2-2827", "description": "Web-based Process Visualization (SCADA/HMI/Dashboard) software", "main": "main.js", "scripts": {
Vulnerability mechanics
Root cause
"The TDengine DAQ storage connector did not properly escape backslashes in user-controlled input, allowing SQL injection."
Attack vector
An attacker sends a crafted `sids` value containing a backslash followed by a single quote (e.g., `x\' OR 1=1--`) through the `GET /api/daq` endpoint or the Socket.IO `DAQ_QUERY` event [ref_id=1]. The `escapeTdString` function doubles single quotes but fails to escape backslashes, allowing the crafted input to break out of the intended string context within the SQL query [ref_id=1]. This enables the attacker to append arbitrary SQL clauses to the query executed against the TDengine server.
Affected code
The vulnerability resides in the `escapeTdString` function located at `server/runtime/storage/tdengine/index.js:10` within the TDengine DAQ storage connector [ref_id=1]. This function is responsible for sanitizing string inputs before they are used in SQL queries.
What the fix does
The patch addresses the vulnerability by improving input escaping in the TDengine connector. While the specific code changes for the `escapeTdString` function are not detailed in the provided patch diffs, the advisory states that version 1.3.2 includes a fix that enhances how user-controlled values are sanitized before being included in SQL queries [ref_id=1]. This prevents specially crafted tag identifiers from altering the executed SQL query.
Preconditions
- networkNetwork access to a FUXA instance.
- configFUXA instance configured with TDengine as the DAQ backend.
- authNo authentication is required in the default configuration, as the `/api/daq` endpoint and the Socket.IO `DAQ_QUERY` handler lack authorization checks [ref_id=1].
Generated on Jun 8, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
0No linked articles in our index yet.