Cross-Site Scripting in typo3/cms-core
Description
TYPO3 is an open source PHP based web content management system released under the GNU GPL. It has been discovered that the f:asset.css view helper is vulnerable to cross-site scripting when user input is passed as variables to the CSS. Update to TYPO3 version 10.4.32 or 11.5.16 that fix the problem. There are no known workarounds for this issue.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
TYPO3's f:asset.css view helper is vulnerable to cross-site scripting when user input is passed as CSS variables, fixed in versions 10.4.32 and 11.5.16.
Vulnerability
Overview
CVE-2022-36108 describes a cross-site scripting (XSS) vulnerability in the TYPO3 content management system, specifically within the f:asset.css view helper. The flaw arises when user-supplied input is passed as variables into CSS definitions without proper encoding. This allows an attacker to inject arbitrary CSS or HTML, potentially leading to script execution in the context of the victim's browser [1].
Exploitation and
Attack Surface
Exploitation requires the ability to control a variable that is used within the f:asset.css view helper. The attacker does not need elevated privileges; any user who can influence such input (e.g., through form fields or URL parameters) can trigger the vulnerability. The attack is reflected or stored depending on how the input is persisted. No authentication is required if the vulnerable template is publicly accessible [1].
Impact
Successful exploitation enables an attacker to inject malicious scripts or styles, leading to session hijacking, defacement, or theft of sensitive data. The vulnerability is classified as high severity due to the potential for widespread impact in TYPO3 installations that use the affected view helper with untrusted data [1].
Mitigation
The issue is patched in TYPO3 versions 10.4.32 and 11.5.16. The fix, visible in the referenced commits [3][4], ensures that child node variables are properly encoded before being rendered in CSS. No workarounds are available; upgrading to the patched versions is strongly recommended [1].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
typo3/cms-corePackagist | >= 10.3.0, < 10.4.32 | 10.4.32 |
typo3/cms-corePackagist | >= 11.0.0, < 11.5.16 | 11.5.16 |
typo3/cmsPackagist | >= 10.3.0, < 10.4.32 | 10.4.32 |
typo3/cmsPackagist | >= 11.0.0, < 11.5.16 | 11.5.16 |
Affected products
4- osv-coords3 versions
>= 10.0.0, < 10.4.31+ 2 more
- (no CPE)range: >= 10.0.0, < 10.4.31
- (no CPE)range: >= 10.3.0, < 10.4.32
- (no CPE)range: >= 10.3.0, < 10.4.32
Patches
26863f73818c3[SECURITY] Encode child node variables in f:asset.css view helper
2 files changed · +75 −1
typo3/sysext/fluid/Classes/ViewHelpers/Asset/CssViewHelper.php+1 −1 modified@@ -51,7 +51,7 @@ final class CssViewHelper extends AbstractTagBasedViewHelper * * @var bool */ - protected $escapeChildren = false; + protected $escapeChildren = true; protected AssetCollector $assetCollector;
typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/CssViewHelperTest.php+74 −0 modified@@ -18,6 +18,8 @@ namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Asset; use TYPO3\CMS\Core\Page\AssetCollector; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Fluid\ViewHelpers\Asset\CssViewHelper; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -79,4 +81,76 @@ public function booleanAttributesAreProperlyConverted(): void self::assertSame($collectedJavaScripts['test']['source'], 'my.css'); self::assertSame($collectedJavaScripts['test']['attributes'], ['disabled' => 'disabled']); } + + public static function childNodeRenderingIsCorrectDataProvider(): array + { + return [ + // Double quotes + 'variable with double quotes is encoded' => [ + '</style>/* " ', // variable value + 'body { color: #{color}; }', // inner template source + 'body { color: #</style>/* " ; }', // expectation + ], + 'variable with double quotes is encoded in single quotes' => [ + '</style>/* " ', // variable value + 'body { color: \'#{color}\'; }', // inner template source + 'body { color: \'#</style>/* " \'; }', // expectation + ], + 'variable with double quotes is encoded in double quotes' => [ + '</style>/* " ', // variable value + 'body { color: "#{color}"; }', // inner template source + 'body { color: "#</style>/* " "; }', // expectation + ], + // Single quotes + 'variable with single quotes is encoded' => [ + '</style>/* \' ', // variable value + 'body { color: #{color}; }', // inner template source + 'body { color: #</style>/* ' ; }', // expectation + ], + 'variable with single quotes is encoded in single quotes' => [ + '</style>/* \' ', // variable value + 'body { color: \'#{color}\'; }', // inner template source + 'body { color: \'#</style>/* ' \'; }', // expectation + ], + 'variable with single quotes is encoded in double quotes' => [ + '</style>/* \' ', // variable value + 'body { color: "#{color}"; }', // inner template source + 'body { color: "#</style>/* ' "; }', // expectation + ], + // Raw instruction + 'raw instruction is passed' => [ + '</style>/* " ', + 'body { color: #{color -> f:format.raw()}; }', + 'body { color: #</style>/* " ; }', + ], + 'raw instruction is passed in sigle quotes' => [ + '</style>/* " ', + 'body { color: \'#{color -> f:format.raw()}\'; }', + 'body { color: \'#</style>/* " \'; }', + ], + 'raw instruction is passed in double quotes' => [ + '</style>/* " ', + 'body { color: "#{color -> f:format.raw()}"; }', + 'body { color: "#</style>/* " "; }', + ], + ]; + } + + /** + * @test + * @dataProvider childNodeRenderingIsCorrectDataProvider + */ + public function childNodeRenderingIsCorrect(string $value, string $source, string $expectation): void + { + $assetCollector = new AssetCollector(); + GeneralUtility::setSingletonInstance(AssetCollector::class, $assetCollector); + + $view = new StandaloneView(); + $view->setTemplateSource(sprintf('<f:asset.css identifier="test">%s</f:asset.css>', $source)); + $view->assign('color', $value); + $view->render(); + GeneralUtility::removeSingletonInstance(AssetCollector::class, $assetCollector); + + self::assertSame($expectation, $assetCollector->getInlineStyleSheets()['test']['source']); + } }
c62e16fac031[SECURITY] Encode child node variables in f:asset.css view helper
2 files changed · +75 −1
typo3/sysext/fluid/Classes/ViewHelpers/Asset/CssViewHelper.php+1 −1 modified@@ -51,7 +51,7 @@ class CssViewHelper extends AbstractTagBasedViewHelper * * @var bool */ - protected $escapeChildren = false; + protected $escapeChildren = true; /** * @var AssetCollector
typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/CssViewHelperTest.php+74 −0 modified@@ -18,6 +18,8 @@ namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Asset; use TYPO3\CMS\Core\Page\AssetCollector; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Fluid\ViewHelpers\Asset\CssViewHelper; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -82,4 +84,76 @@ public function booleanAttributesAreProperlyConverted(): void self::assertSame($collectedJavaScripts['test']['source'], 'my.css'); self::assertSame($collectedJavaScripts['test']['attributes'], ['disabled' => 'disabled']); } + + public static function childNodeRenderingIsCorrectDataProvider(): array + { + return [ + // Double quotes + 'variable with double quotes is encoded' => [ + '</style>/* " ', // variable value + 'body { color: #{color}; }', // inner template source + 'body { color: #</style>/* " ; }', // expectation + ], + 'variable with double quotes is encoded in single quotes' => [ + '</style>/* " ', // variable value + 'body { color: \'#{color}\'; }', // inner template source + 'body { color: \'#</style>/* " \'; }', // expectation + ], + 'variable with double quotes is encoded in double quotes' => [ + '</style>/* " ', // variable value + 'body { color: "#{color}"; }', // inner template source + 'body { color: "#</style>/* " "; }', // expectation + ], + // Single quotes + 'variable with single quotes is encoded' => [ + '</style>/* \' ', // variable value + 'body { color: #{color}; }', // inner template source + 'body { color: #</style>/* ' ; }', // expectation + ], + 'variable with single quotes is encoded in single quotes' => [ + '</style>/* \' ', // variable value + 'body { color: \'#{color}\'; }', // inner template source + 'body { color: \'#</style>/* ' \'; }', // expectation + ], + 'variable with single quotes is encoded in double quotes' => [ + '</style>/* \' ', // variable value + 'body { color: "#{color}"; }', // inner template source + 'body { color: "#</style>/* ' "; }', // expectation + ], + // Raw instruction + 'raw instruction is passed' => [ + '</style>/* " ', + 'body { color: #{color -> f:format.raw()}; }', + 'body { color: #</style>/* " ; }', + ], + 'raw instruction is passed in sigle quotes' => [ + '</style>/* " ', + 'body { color: \'#{color -> f:format.raw()}\'; }', + 'body { color: \'#</style>/* " \'; }', + ], + 'raw instruction is passed in double quotes' => [ + '</style>/* " ', + 'body { color: "#{color -> f:format.raw()}"; }', + 'body { color: "#</style>/* " "; }', + ], + ]; + } + + /** + * @test + * @dataProvider childNodeRenderingIsCorrectDataProvider + */ + public function childNodeRenderingIsCorrect(string $value, string $source, string $expectation): void + { + $assetCollector = new AssetCollector(); + GeneralUtility::setSingletonInstance(AssetCollector::class, $assetCollector); + + $view = new StandaloneView(); + $view->setTemplateSource(sprintf('<f:asset.css identifier="test">%s</f:asset.css>', $source)); + $view->assign('color', $value); + $view->render(); + GeneralUtility::removeSingletonInstance(AssetCollector::class, $assetCollector); + + self::assertSame($expectation, $assetCollector->getInlineStyleSheets()['test']['source']); + } }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-fv2m-9249-qx85ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-36108ghsaADVISORY
- github.com/FriendsOfPHP/security-advisories/blob/master/typo3/cms-core/CVE-2022-36108.yamlghsaWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/typo3/cms/CVE-2022-36108.yamlghsaWEB
- github.com/TYPO3/typo3/commit/6863f73818c36b0b88c677ba533765c8074907b4ghsax_refsource_MISCWEB
- github.com/TYPO3/typo3/commit/c62e16fac031c270d9759c7261e504c7e25405dfghsaWEB
- github.com/TYPO3/typo3/security/advisories/GHSA-fv2m-9249-qx85ghsax_refsource_CONFIRMWEB
- typo3.org/security/advisory/typo3-core-sa-2022-010ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.