Miggo Logo

CVE-2025-48203:
[clickstorm] SEO (cs_seo) TYPO3 extension Cross-site Scripting (XSS) vulnerability

5.1

CVSS Score

Basic Information

EPSS Score
-
Published
5/21/2025
Updated
5/21/2025
KEV Status
No
Technology
TechnologyPHP

Technical Details

CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:L/E:F/RL:O/RC:C
Package NameEcosystemVulnerable VersionsFirst Patched Version
clickstorm/cs-seocomposer>= 9.0.0, < 9.3.09.3.0
clickstorm/cs-seocomposer>= 8.0.0, < 8.4.08.4.0
clickstorm/cs-seocomposer>= 7.0.0, < 7.5.07.5.0
clickstorm/cs-seocomposer>= 6.3.0, < 6.8.06.8.0

Vulnerability Intelligence
Miggo AIMiggo AI

Miggo AIRoot Cause Analysis

The vulnerability is a Cross-site Scripting (XSS) issue in the JSON-LD output. I analyzed the provided commit 1cf6c40821102b1f1508fe4e76825569340c8f90 which patches this vulnerability.

  1. The core of the XSS vulnerability lay in the Clickstorm\CsSeo\UserFunc\StructuredData::wrapWithLd function. The original version of this function directly embedded the provided content string into an HTML <script type="application/ld+json"> tag without any escaping. This meant any HTML metacharacters or script tags within the content would be rendered by the browser, causing XSS. The patch fixed this by applying htmlspecialchars to the content.
  2. The Clickstorm\CsSeo\UserFunc\StructuredData::getJsonLdOfPageOrRecord function was identified as vulnerable because it fetched JSON-LD data (specifically from $metaData['json_ld'], which is a likely point for user input) and passed it to the wrapWithLd function. If this input was malicious, getJsonLdOfPageOrRecord facilitated the XSS by channeling the tainted data to the vulnerable output function. The patch added JSON decoding and re-encoding as a sanitization step for the data handled by this function before it's passed to wrapWithLd.
  3. The Clickstorm\CsSeo\Evaluation\TCA\JsonLdEvaluator::evaluateFieldValue function was involved in validating the JSON-LD data on the backend during save operations. Its original sanitization logic, which only stripped <script> tags, was insufficient to prevent XSS payloads embedded within the JSON structure itself. This weakness allowed malicious JSON-LD to be stored, which would then be rendered by the vulnerable wrapWithLd function. The patch improved the validation logic in this function.

All three functions played a role: evaluateFieldValue in allowing malicious data to be saved, getJsonLdOfPageOrRecord in processing and passing this data, and wrapWithLd in unsafely rendering it, which is the direct cause of the XSS.

Vulnerable functions

Clickstorm\CsSeo\UserFunc\StructuredData::wrapWithLd
Classes/UserFunc/StructuredData.php
This function, in its original form, directly concatenated the input `$content` (JSON-LD string) into a `<script>` tag without any HTML escaping. If `$content` contained malicious HTML/JavaScript (e.g., `</script><script>alert(1)</script>`), it would be rendered by the browser, leading to XSS. This is the direct point of injection in the output.
Clickstorm\CsSeo\UserFunc\StructuredData::getJsonLdOfPageOrRecord
Classes/UserFunc/StructuredData.php
This function retrieves JSON-LD data, potentially from user-controlled sources via `$metaData['json_ld']`. In its vulnerable version, it passed this data directly to the `wrapWithLd` function. If the `$metaData['json_ld']` contained malicious script content, this function would facilitate its passage to the vulnerable rendering point in `wrapWithLd`.
Clickstorm\CsSeo\Evaluation\TCA\JsonLdEvaluator::evaluateFieldValue
Classes/Evaluation/TCA/JsonLdEvaluator.php
This function is responsible for server-side validation of the JSON-LD data when a record is saved. The original implementation only attempted to strip `<script>` tags using `preg_replace('#<script(.*?)>|</script>#is', '', $value)`. This sanitization was insufficient as XSS payloads can be embedded within JSON string values without using explicit `<script>` tags (e.g., using event handlers or other contexts within the JSON that could be interpreted as script by the browser when rendered by `wrapWithLd`). This function allowed inadequately sanitized, potentially malicious JSON-LD to be persisted.

WAF Protection Rules

WAF Rule

*ross-sit* s*riptin* (XSS) vuln*r**ility in t** [*li*kstorm] S*O (*s_s*o) TYPO* *xt*nsion *llows ***k*n* us*rs to *x**ut* *r*itr*ry s*ript vi* t** JSON-L* output.

Reasoning

T** vuln*r**ility is * *ross-sit* S*riptin* (XSS) issu* in t** JSON-L* output. I *n*lyz** t** provi*** *ommit `****************************************` w*i** p*t***s t*is vuln*r**ility. *. T** *or* o* t** XSS vuln*r**ility l*y in t** `*li*kstorm\*sS