CVE-2026-77616: Semantic MediaWiki affected by reflected XSS in `Special:Ask` via a forged cursor pagination token
Reflected XSS via a forged cursor pagination token
Failure mode
Special:Ask accepts a cursor query parameter for keyset pagination (added in 7.0.0). The token is decoded by CursorEncoder, which is an unsigned base64url-encoded JSON blob, so its contents are fully attacker-controlled. When the cursor's sort anchor does not match the request's sort= / order=, QueryCreator::applyCursorIfRequested() builds an error message by interpolating the attacker-controlled sortprop / sortorder values into a raw string via Query::addErrors().
Unlike SMW's message-key errors, this raw string bypasses the message layer's sanitisation (ProcessingErrorMsgHandler::normalizeAndDecodeMessages() passes a non-key, non-encoded string through unchanged). ErrorWidget::queryError() then assembles the errors and passes them to Html::errorBox(), whose first argument is emitted as raw HTML. The result is a reflected cross-site scripting vulnerability: a crafted cursor token containing markup in sortprop (or sortorder) executes script in the victim's browser on the wiki origin.
No authentication or special permission is required. The payload is delivered via a crafted link, e.g. Special:Ask?q=...&p[cursor]=<forged token> where the token decodes to {"v":1,"sortprop":"<script>...</script>"}. Confirmed executing in a browser; the responses carry no Content-Security-Policy, so inline script is not blocked.
Remediation
- Output-encode the attacker-controlled sortprop / sortorder values before they are interpolated into the error text in QueryCreator, so no raw user input enters the error stream. - Defense in depth: the format=debug output path that reflected the same error text was hardened separately in GHSA-q5fm-9mx6-44f4.
Maintenance note
Query error strings are rendered as raw HTML by ErrorWidget::queryError() via Html::errorBox(). Any error added through Query::addErrors() that embeds user-controlled text must be output-encoded (or use a message key); pagination and validation error text is attacker-influenced and must not be treated as trusted.
Other sources
Semantic MediaWiki is a free, open-source extension to MediaWiki that lets users store and query data within the wiki's pages. In versions 7.0.0 through 7.1.0, Special:Ask accepts a cursor query parameter for keyset pagination (added in 7.0.0). The token is decoded by CursorEncoder, which is an unsigned base64url-encoded JSON blob, so its contents are fully attacker-controlled. When the cursor's sort anchor does not match the request's sort= / order=, QueryCreator::applyCursorIfRequested() builds an error message by interpolating the attacker-controlled sortprop / sortorder values into a raw string via Query::addErrors(). Unlike SMW's message-key errors, this raw string bypasses the message layer's sanitization (ProcessingErrorMsgHandler::normalizeAndDecodeMessages() passes a non-key, non-encoded string through unchanged). ErrorWidget::queryError() then assembles the errors and passes them to Html::errorBox(), whose first argument is emitted as raw HTML. The result is a reflected cross-site scripting vulnerability: a crafted cursor token containing markup in sortprop (or sortorder) executes script in the victim's browser on the wiki origin. No authentication or special permission is required. The payload is delivered via a crafted link. Version 7.2.0 contains a fix.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
composer/mediawiki/semantic-media-wikito a version that resolves this vulnerability.Fixed in 7.2.0 - Upgrade
Upgrade
Semantic MediaWikito a version that resolves this vulnerability.Fixed in 7.2.0Patch GHSA-q5fm-9mx6-44f4 - Configuration
In QueryCreator, output-encode attacker-controlled `sort_prop` / `sort_order` values before interpolating them into the error text added via `Query::addErrors()` for cursor mismatch errors (since ErrorWidget::queryError() renders errors as raw HTML via Html::errorBox()).
Semantic MediaWiki (QueryCreator / Query::addErrors / ErrorWidget / Html::errorBox) output encoding of attacker-controlled sort_prop/sort_order = output-encode sort_prop and sort_order before interpolating into error text (no raw user input in error stream; error strings must be output-encoded or use a message key)
Event History
Frequently Asked Questions
What does an attacker need to exploit this issue?
An attacker can craft a URL containing a forged cursor token and send it to a victim. No authentication or special permission is required, but the victim must visit the crafted URL.
Which deployments are exposed?
Deployments exposing Special:Ask with cursor-based keyset pagination are relevant. Cursor pagination was added in 7.0.0, and the issue is reachable through the cursor query parameter.
What is the impact when a victim follows a malicious link?
Attacker-controlled markup in the forged cursor can execute in the victim's browser under the wiki's origin. This can expose data accessible to that user and allow actions within that user's browser session.