See how semantic mediawiki compares to other vendors in security performance
Query debug output XSS
Failure mode
Semantic MediaWiki's query debug output (format=debug, or the debug request parameter on Special:Ask) is assembled by SMW\Query\DebugFormatter and emitted as raw HTML. Several of its sinks apply no output-context encoding, so attacker-controlled query input is reflected into the page without escaping:
- buildHTML() echoes the re-serialized ASK query string escaping only [; <, >, ", ' pass through. - prettifySQL() returns the generated SQL verbatim. Query value literals are inlined into the SQL through the database layer's quoting (SQL-escaping only, no HTML encoding), so markup in a value survives. - prettifyExplain() echoes EXPLAIN output; on PostgreSQL the plan text contains the WHERE literals.
On Special:Ask the resulting string is concatenated into the page and sent through OutputPage::addHTML, never through the MediaWiki parser or Sanitizer. No special user right is required; an anonymous request suffices.
This is a reflected XSS: the payload is taken from the request and echoed in the same response. Exploitation requires the query condition to target a text/blob-typed property (whose value is re-serialized verbatim); the predefined txt properties (Text, etc.) that ship on every install satisfy this, so no attacker-created content is needed. Example request:
Special:Ask?q=[[Text::<script>alert(document.domain)</script>]]&debug=1
Remediation
- Apply output-context escaping at the DebugFormatter boundary. The buildHTML() contract already assumes its inputs are HTML-safe, but its callers do not honour that; escape each entry value on emission, and the SQL and EXPLAIN strings before they are wrapped. - Escaping only the query-string echo is insufficient: prettifySQL() and the "Auxilliary Tables" executed-query text carry the same attacker-controlled literals.
Scope
The prettifySPARQL() sink already encodes < and > and is not affected. The same debug path is also reachable through inline {{#ask:...|format=debug}}, but that output returns into parser context and is sanitized there; the reflected Special:Ask path is the exposed sink.
Relationship to GHSA-5jhc-3j2f-52rv
This issue was identified while splitting the consolidated report GHSA-5jhc-3j2f-52rv into per-vulnerability advisories. It is distinct from the four items in that report (plain table header, sep, SearchByProperty value, open redirect) and from Special:Ask form-input XSS (which is escaped separately).
Failure mode
Special:URIResolver resolves its user-controlled subpage to a MediaWiki title and issues an HTTP 303 redirect to $title->getFullURL() without validating the resolved target. A crafted subpage can make that target point off-host: an interwiki prefix redirects to the foreign wiki (for example Special:URIResolver/mw-3AFoo, which decodes to mw:Foo, redirects to https://www.mediawiki.org/wiki/Foo), and where the resolved URL carries an authority the target can even embed user:pass@host credentials. The result is an open redirect to an attacker-influenced host, usable for phishing from a trusted wiki URL.
Remediation
- The resolved target URL is parsed and compared against the current host at the redirect sink. - The redirect is rejected (bad-title error page) when a user or pass component is present, or when the host does not match the current host.
Maintenance note
Redirect code must validate the final target URL, not just the input path. Host comparison belongs at the redirect sink: each sink (special page, entry point) must validate its own target rather than relying on upstream normalisation.
Failure mode
sep was inserted verbatim into the HTML that joins a table cell's values. This made it possible to inject HTML through the separator value. The same unsanitised table HTML is produced both for the standard Special:Ask render and for its raw request output (requesttype=raw), so the injection was reachable without authentication.
Remediation
- In all non-wiki output modes (HTML, raw request, file), sep is escaped unless it is a safe <br> variant. - This preserves legitimate line-break separators while blocking markup injection.
Maintenance note
If the table renderer ever gains richer separator semantics, keep the whitelist explicit. Do not expand the allowed HTML surface casually.
Failure mode
The value parameter was reflected back into rendered output and error messaging paths without enough output-context encoding.
Remediation
- The form value is escaped before it is placed back into the input field. - Derived error messages are also escaped before being rendered into HTML.
Maintenance note
Do not treat error text as trusted just because it originated from validation. Validation output can still be attacker-influenced.
Failure mode
When headers=plain, table header text was emitted into <th> via a raw HTML path. User-controlled mainlabel content could therefore become executable HTML.
Remediation
- TableResultPrinter now applies output-context escaping before passing plain headers to the table renderer. - The fix is limited to the HTML/plain-header branch so safe rendering modes are unaffected.
Why this is the right layer
The header value is not a structural token; it is display data. Sanitizing it at the sink is correct because the renderer owns the final HTML emission.
Cross-Site Scripting (XSS) vulnerability reflected in Semantic MediaWiki. This vulnerability allows an attacker to execute JavaScript code in the victim's browser by sending them a malicious URL using the '/index.php/Speciaal:GefacetteerdZoeken' endpoint parameter. This vulnerability can be exploited to steal sensitive user data, such as session cookies, or to perform actions on behalf of the user.