
Loading

Loading
We use strictly necessary cookies to run this site, and analytics cookies to understand how it's used. See our Privacy Policy for details.
A GitHub-reviewed security advisory, not necessarily under active exploitation the way our CISA KEV advisories are, but a real, disclosed vulnerability in an open-source dependency.
Affected packages
Vulnerable: >= 4.2.0, <= 7.2.0
Patched in 7.2.1
Details
Special:FacetedSearch cstate hidden inputs enable reflected XSS (residual of CVE-2025-10354)
SemanticMediaWiki/[email protected].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.
Talk to us about this
Find out whether this dependency (or others like it) is actually reachable in your codebase.
Get help patching, or building dependency-scanning into your pipeline going forward.
A secure code review or supply chain review finds this before an advisory does.