Craft CMS: The Art of SQL Injection via Mass Assignment
Vulnerability ID: CVE-2026-25495
CVSS Score: 8.7
Published: 2026-02-09
A high-severity SQL injection vulnerability in Craft CMS allows authenticated Control Panel users to execute arbitrary SQL commands. The flaw stems from a mass assignment vulnerability where user-supplied JSON keys are directly mapped to query builder methods, specifically bypassing sanitization mechanisms in the underlying Yii2 framework.
TL;DR
Authenticated attackers can turn the Craft CMS Control Panel into a SQL playground. By sending a crafted JSON payload to the element index endpoint, you can inject raw SQL into the 'ORDER BY' clause. This happens because the code blindly applies user input to the database query builder object.
⚠️ Exploit Status: POC
Technical Details
- CWE ID: CWE-89
- CVSS v4.0: 8.7 (High)
- Attack Vector: Network (Authenticated)
- Exploit Status: PoC Available
- Vulnerability Type: SQL Injection via Mass Assignment
- Affected Component: ElementIndexesController (get-elements)
Affected Systems
- Craft CMS 4.x < 4.16.18
- Craft CMS 5.x < 5.8.22
-
Craft CMS: >= 4.0.0-RC1, <= 4.16.17 (Fixed in:
4.16.18) -
Craft CMS: >= 5.0.0-RC1, <= 5.8.21 (Fixed in:
5.8.22)
Code Analysis
Commit: 96c60d7
Fix SQL injection via criteria param
- Craft::configure($query, Component::cleanseConfig($criteria));
+ unset($criteria['where'], $criteria['orderBy'], ...);
+ Craft::configure($query, Component::cleanseConfig($criteria));
Exploit Details
- Manual Analysis: Time-based blind SQL injection via the 'orderBy' parameter in the criteria object.
Mitigation Strategies
- Upgrade Immediately: This is the only reliable fix.
- WAF Filtering: Block requests to 'element-indexes/get-elements' where the body contains 'criteria' with keys like 'orderBy', 'union', or 'join'.
- Least Privilege: Ensure Control Panel accounts are strictly audited and use strong MFA.
Remediation Steps:
- Run
composer updatein your Craft CMS project root. - Verify that
craftcms/cmsis updated to at least version 4.16.18 or 5.8.22. - Check
composer.lockto ensure the package version is pinned correctly. - Restart PHP-FPM/Nginx to clear any opcode caches.
References
Read the full report for CVE-2026-25495 on our website for more details including interactive diagrams and full exploit analysis.
Top comments (0)