Special:FacetedSearch cstate hidden inputs enable reflected XSS (residual of CVE-2025-10354)
SemanticMediaWiki/SemanticMediaWiki@7.2.0.master at HEAD 18f418b4cdf2875e67a741349179a22c1573f61c.Vulnerable sink (default-branch representation):
src/MediaWiki/Specials/FacetedSearch/HtmlBuilder.php:131-133
$hidden by concatenating unescaped request-controlled cstate[$key] values into an HTML attribute context (value="...").templates/FacetedSearch/search.mustache:25
{{{hidden}}} (no HTML escaping at this boundary).GET to Special:FacetedSearch dispatches into SMW\MediaWiki\Specials\SpecialFacetedSearch::execute().SpecialFacetedSearch::execute() constructs UrlArgs from $request->getValues() and calls ParametersProcessor::checkRequest($request).ParametersProcessor::checkRequest() clears cstate only when filtered != 1 and getInt('csum', 0) != crc32(getVal('q', '')).HtmlBuilder::buildHTML() iterates foreach ( $urlArgs->getArray( 'cstate' ) as $key => $value ) and concatenates each into $hidden without escaping.HtmlBuilder::buildHTML() passes $hidden into the template variable hidden.templates/FacetedSearch/search.mustache renders {{{hidden}}} into the <form>, so the concatenated markup is inserted as raw HTML.q value.csum as crc32(q).q=<chosen>csum=<crc32(q)>cstate[<key>]=<payload> entryExample request shape:
/index.php/Special:FacetedSearch?q=Text&csum=<crc32(Text)>&cstate[0]=x%22%20autofocus%20onfocus%3Dalert(1)%20x%22
Special:FacetedSearch (or the localized alias mapped to the same SpecialFacetedSearch class) can supply attacker-controlled query parameters.cstate survive ParametersProcessor::checkRequest(), either by setting csum to crc32(q) (when filtered != 1), or by setting filtered=1.cstate[<key>] values containing characters that break out of the HTML value="..." attribute context (for example an injected " to terminate the attribute value).Proposed severity: MEDIUM.
Proposed CVSS v3.1 vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N.
Rationale:
q, csum, and at least one cstate entry.q parameter before emitting it into the value="{{q}}" attribute.3d675ce updates only the q rendering to use htmlspecialchars( $urlArgs->get( 'q', '' ) ) and does not touch the adjacent cstate -> $hidden construction loop.cstate remains an unescaped input source that flows into the same raw template injection point ({{{hidden}}}), creating a distinct reflected-XSS lane.Given the payload idea where cstate[0] starts with x" ... x", HtmlBuilder.php constructs the hidden fragment by concatenation:
<input name="cstate[0]" type="hidden" value="x" autofocus onfocus=alert(1) x">
Because search.mustache injects the fragment via {{{hidden}}}, the attacker-controlled markup participates in normal HTML parsing in the response body.
cstate key and value when constructing $hidden.src/MediaWiki/Specials/FacetedSearch/HtmlBuilder.php:foreach ( $urlArgs->getArray( 'cstate' ) as $key => $value ) {
$safeKey = htmlspecialchars( (string)$key, ENT_QUOTES, 'UTF-8' );
$safeValue = htmlspecialchars( (string)$value, ENT_QUOTES, 'UTF-8' );
$hidden .= '<input name="cstate[' . $safeKey . ']" type="hidden" value="' . $safeValue . '">';
}
This keeps the raw {{{hidden}}} template insertion safe by ensuring the concatenated HTML fragment itself is attribute-escaped.
I anchored on the published CVE-2025-10354 patch by verifying in the checked-out repository that commit 3d675ce changes only the q rendering in HtmlBuilder.php to use htmlspecialchars.
Then I traced the reachable request path from SpecialFacetedSearch::execute() through ParametersProcessor::checkRequest() (checksum gate for whether cstate survives) into HtmlBuilder::buildHTML() where $hidden is constructed from cstate without escaping and injected into templates/FacetedSearch/search.mustache via {{{hidden}}}.
(End of file)
I used AI assistance for the code audit and for drafting this report. I manually verified the finding against the project's source at the location cited above before reporting it, and the severity and impact assessment are my own.
{
"cwe_ids": [
"CWE-79"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-18T16:59:16Z",
"nvd_published_at": null,
"severity": "MODERATE"
}