Submit #916011: Scada-LTS 2.8.0 Improper Authorizationinfo

TitleScada-LTS 2.8.0 Improper Authorization
DescriptionInsecure direct object reference (broken object-level authorization) in the AmCharts data API of Scada-LTS 2.8.0 (commit f2a519bf). GET /Scada-LTS/api/amcharts/by-id (and /by-xid) is protected only by the Spring Security expression @guard.hasDataPointReadPermission(request, false, 'ids'). The guard resolves the ids parameter with HttpServletRequest.getParameter(), which returns only the FIRST value of a multi-valued parameter, while the controller binds @RequestParam Set<Integer> ids, that is, all of them. Any authenticated user, including a low-privileged ROLE_USER, can therefore place a data point they are allowed to read, or a non-existent id, first in the request, and the controller then returns the value history of every other data point id in the same request, bypassing the per-object read permission. Affected code: WebContent/WEB-INF/spring-security.xml:411 <intercept-url pattern="/api/amcharts/by-id" access="@guard.hasDataPointReadPermission(request,false,'ids')" method="GET" /> GetIdentifierFromHttpParameterGuard.java:213 hasDataPointReadPermission(request, isXid, "ids") -> :290 return HttpParameterUtils.getValueOnlyRequest(idName, request, identifier -> doHasPermission(...)).orElse(false); HttpParameterUtils.java:40 getValueOnlyRequest(...) <-- the sink 41 String parameter = request.getParameter(key); // only the FIRST value of ids is read 42 if (parameter != null) 43 return Optional.ofNullable(parse(parser, parameter)); HasPermissionOperations.java:48 hasDataPointReadPermission(user, <that first id>) -> private hasPermission(...): 200 if (object == null) { ...; return true; } // fail-open when the id does not resolve (193 an EmptyResultDataAccessException for an unknown id is likewise treated as "return true") AmChartValuesAPI.java:113 @GetMapping("/by-id") 114 getValuesFromTimeRangeById(@RequestParam Set<Integer> ids, ...) // binds ALL ids 146 getPointValuesFromRangeById(...) -> 147 List<DataPointVO> dataPoints = dpService.getDataPoints(pointIds); // no per-object permission filter The guard inspects only ids[0]; the controller returns values for every id in the set. A first value the user may legitimately read, or a non-existent one via the fail-open path above, passes the guard, and the response then includes any other point's data. Impact: a low-privileged authenticated user can read the recorded value history of any data point in the system, that is, arbitrary process and sensor telemetry, regardless of the per-object read permissions an administrator has configured. The issue is read-only and affects confidentiality. Reproduction. Authenticate as a low-privileged user with no read permission on the target data point (form login, POST /Scada-LTS/login.htm with username and password), then compare two requests that differ only in the ids parameter: GET /Scada-LTS/api/amcharts/by-id?ids=1&startTs=0&endTs=9999999999999 -> HTTP 403 (denied, as expected) GET /Scada-LTS/api/amcharts/by-id?ids=999999&ids=1&startTs=0&endTs=9999999999999 -> HTTP 200, response body contains the value history of data point 1 Same user, same target id. 999999 is simply an id that does not exist, which passes the guard through the fail-open branch; any data point the user is permitted to read works equally well as the first value. A self-contained Docker lab (stock scadalts/scadalts:latest image plus MySQL) and a proof-of-concept script were supplied to the vendor and can be provided to the VulDB team on request. The proof-of-concept performs the two requests above and reports the 403 versus 200 result. 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 the @guard layer and AmChartValuesAPI is expected to be affected. The code is unpatched on the current master and develop branches. CWE-639 (authorization bypass through user-controlled key), also CWE-863 (incorrect authorization). 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 is rated high because the flaw bypasses the per-object read authorization model for every data point in the installation; integrity and availability are unaffected as the endpoint is read-only. 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)
Submission08/05/2026 12:46 (3 months ago)
Moderation10/23/2026 17:14 (3 months later)
StatusAccepted
VulDB entry425987 [Scada-LTS 2.8.0 AmCharts Data API AmChartValuesAPI.java HttpServletRequest.getParameter ids authorization]
Points17

Do you know our Splunk app?

Download it now for free!