| Title | Scada-LTS 2.8.0 SQL Injection |
|---|
| Description | Authenticated SQL injection in the event search REST API of Scada-LTS 2.8.0 (commit f2a519bf).
POST /Scada-LTS/api/events/search accepts a JSON body whose sortBy array is concatenated directly into the SQL ORDER BY clause, without parameterization, in EventDAO.findEvents.
Affected code, src/org/scada_lts/dao/event/EventDAO.java (findEvents):
~924 sorting.add(query.getSortBy()[i] + " " + (query.getSortDesc()[i] ? "DESC " : "ASC "));
~927 sql.append("ORDER BY " + String.join(", ", sorting));
~939 DAO.getInstance().getJdbcTemp().query(sql.toString(), params.toArray(), ...);
The bound parameters cover only the WHERE and keyword placeholders. The ORDER BY fragment is fully attacker-controlled; only the literal value "status" is special-cased. The endpoint is EventsAPI.getEvents (EventsAPI.java:155). Its only access control check is that the session is authenticated, and spring-security.xml grants /api/events/** to ROLE_USER. CSRF protection is disabled for the API filter chain. A single low-privileged user session is therefore sufficient.
Impact: any authenticated user, including an unprivileged ROLE_USER account, can read arbitrary database contents using blind boolean-based and time-based techniques, including the users table. Password hashes stored there are unsalted SHA-1 (Base64) and crack offline almost immediately; the default admin hash is simply SHA-1 of "admin". Recovering an administrator password this way additionally unlocks the documented authenticated command execution feature (Event Handlers, CVE-2023-33472), so in practice the injection gives an unprivileged user a path toward full compromise. The issue reported here is the SQL injection itself.
Reproduction. Authenticate as any user (form login, POST /Scada-LTS/login.htm with username and password), then POST to /Scada-LTS/api/events/search with Content-Type: application/json and the body:
{"startDate":"","endDate":"","startTime":"","endTime":"","alarmLevel":0,"keywords":"","status":"","eventSourceType":0,"datapoint":"","limit":10,"offset":0,"sortDesc":[false],"sortBy":["e.id"]}
Varying only the sortBy element gives a clear differential, which confirms the value reaches the ORDER BY clause unsanitised:
sortBy ["e.id"] -> HTTP 200 (valid column)
sortBy ["sqli_probe_zzz"] -> HTTP 500 (unknown column, i.e. input reached ORDER BY)
The same differential works as a boolean oracle, returning 200 when the injected condition is true and 500 when it is false, because the false branch produces a sub-select with cardinality greater than one:
sortBy ["(select case when (1=1) then e.id else (e.id+(select 1 union select 2)) end)"] -> HTTP 200
sortBy ["(select case when (1=2) then e.id else (e.id+(select 1 union select 2)) end)"] -> HTTP 500
Substituting an arbitrary condition for 1=1 allows blind extraction of arbitrary database content, character by character. A time-based variant using SLEEP() behaves equivalently.
A self-contained Docker lab (stock scadalts/scadalts:latest image plus MySQL) and a full proof-of-concept script were supplied to the vendor and can be provided to the VulDB team on request. The proof-of-concept demonstrates the injection three ways, the response differential above, a boolean oracle and a time-based delay, then extracts @@version, the current database name, and name/hash pairs from the users table. It performs no privilege escalation and no code execution.
Affected versions: 2.8.0 verified. By code lineage the remainder of the 2.x line shipping this endpoint is expected to be affected. The code is unpatched on the current master and develop branches.
CWE-89. Suggested CVSS v3.1 vector: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N (base 6.5). Confidentiality impact is high (full database read); integrity and availability are rated none because the injection point is an ORDER BY clause and stacked queries are not available through the JDBC connection.
This is distinct from CVE-2023-33472 (Event Handlers code injection) and from the product's known XSS, CSRF and path traversal issues. No CVE is known to cover it.
Disclosure timeline: 2026-06-28 reported privately to the vendor at [email protected], with the Docker lab and proof-of-concept attached, per the project's security policy. No vendor response as at 2026-08-05. Researchers: Lian Aldrich and Jacob Simmons, Aphotic Security.
|
|---|
| User | LianAldrich (UID 43919) |
|---|
| Submission | 08/05/2026 12:43 (2 months ago) |
|---|
| Moderation | 09/25/2026 12:09 (2 months later) |
|---|
| Status | Duplicate |
|---|
| VulDB entry | 405989 [ScadaLTS 2.8.1-release-candidate build 0 Search Endpoint spring-security.xml sortBy sql injection] |
|---|
| Points | 0 |
|---|