
LimeSurvey 7.0.5 - Stored XSS in Survey Menu Entries
8.4
High
Detected by

Fluid Attacks AI SAST Scanner
Disclosed by
Miguel Gómez
Summary
Full name
LimeSurvey 7.0.5 - Stored XSS in Survey Menu Entries
Code name
State
Public
Release date
Affected product
LimeSurvey
Vendor
LimeSurvey
Affected version(s)
7.0.5
Vulnerability name
Stored cross-site scripting (XSS)
Vulnerability type
Remotely exploitable
Yes
CVSS v4.0 vector string
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:P/VC:H/VI:H/VA:N/SC:L/SI:L/SA:N
CVSS v4.0 base score
8.4
Exploit available
Yes
CVE ID(s)
Description
LimeSurvey Community Edition 7.0.5 contains a stored cross-site scripting vulnerability in the Survey Menu Entries administration page. An authenticated user with the global settings:read permission can create a survey menu entry containing attacker-controlled data. The value is stored in the surveymenu_entries.data field and later inserted into a single-quoted HTML title attribute without context-appropriate encoding.
When another authorized user opens the Survey Menu Entries page, a quote-breaking payload can terminate the attribute and inject HTML with an event handler. The JavaScript executes in the victim's authenticated LimeSurvey browser session and can perform actions available to that victim.
Vulnerability
Root cause
Insufficient authorization on creation.
SurveymenuEntryController::__construct()only requiressettings:read(application/controllers/admin/SurveymenuEntryController.php:13-21). Thecreate()action does not independently requiresettings:create(application/controllers/admin/SurveymenuEntryController.php:98-115).Attacker-controlled value is persisted.
create()assigns$_POST['SurveymenuEntries']to the model, and the model marksdataas safe without an XSS-specific validator (application/controllers/admin/SurveymenuEntryController.php:105-107,application/models/SurveymenuEntries.php:49-64). The update path performs the same assignment for users withsettings:update(application/controllers/admin/SurveymenuEntryController.php:124-156).Unsafe HTML sink.
SurveymenuEntries::getColumns()concatenates$data->datainto an HTML attribute and marks the result as raw (application/models/SurveymenuEntries.php:401-407):
Confirmed source-to-sink path
An authenticated low-privileged user submits
SurveymenuEntries[data]toPOST /index.php/admin/menuentries/sa/create.SurveymenuEntryController::create()copies the field into aSurveymenuEntriesmodel and saves it.The value is persisted in the
surveymenu_entries.datacolumn.GET /index.php/admin/menuentries/sa/viewloads the records and invokesSurveymenuEntries::getColumns().The stored value is placed inside
title='...'and returned as raw HTML.A payload such as
'><img src=x onerror="alert(document.domain)">closes the attribute and creates an executable event handler.
Related update path
POST /index.php/admin/menuentries/sa/update/id/0 also creates a new SurveymenuEntries model. The main-menu restriction is checked before POST data is assigned, while the new model has no main-menu ID yet (application/controllers/admin/SurveymenuEntryController.php:128-151). A user with settings:update can therefore submit menu_id=1 or menu_id=2 through this path and persist the same payload.
PoC
Preconditions
LimeSurvey Community Edition 7.0.5+260623.
An authenticated account with global
settings:readpermission for the creation path.A valid CSRF token and session cookie.
A second authorized user who opens the Survey Menu Entries page. The impact is determined by the victim's permissions.
Creation path
Send an authenticated form request to:
The payload may also be supplied using a unique marker, for example:
After the record is stored, have an authorized user request:
Expected result:
The response contains the stored payload in an unescaped
titleattribute.The injected image handler executes when the table is rendered.
JavaScript runs in the victim's authenticated LimeSurvey session.
Update path
An authenticated user with settings:update can send the same payload to:
Include SurveymenuEntries[data] and SurveymenuEntries[menu_id]=1 in the request body. The id=0 path reaches a new model before the submitted menu ID is applied, so the main-menu check does not prevent the write.
Evidence of Exploitation
Video of exploitation:
Static evidence:

Our security policy
We have reserved the ID CVE-2026-15973 to refer to this issue from now on.
System Information
LimeSurvey
Version: 7.0.5
Operating System: Any
References
GitHub Repository: https://github.com/LimeSurvey/LimeSurvey/
Mitigation
There is currently no patch available for this vulnerability.
Credits
The vulnerability was discovered by Miguel Gomez from Fluid Attacks' Offensive Team using the AI SAST Scanner.
Timeline
Vulnerability discovered
Vendor contacted
Public disclosure
Does your application use this vulnerable software?
During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.














