Using the power of your CMS to block Cross-Site-Scripting injections

|Benni Mack
Illustration of a computer screen with code and warning symbols, representing Cross-Site Scripting (XSS) attacks.

In our previous blog post, we've touched on most elements of Content Security Policy (CSP) to mitigate any kind of injection via Cross-Site-Scripting. If you haven't caught up yet, be sure to read Part 1 first. Now, let's dive into the practical part on how to make your TYPO3 site more secure by sending CSP Headers by default.

Dream Team: TYPO3 and Security

TYPO3's low track record™ isn’t just there because of the minimum amount of security issues while powering hundreds of thousands of websites. In the past years, each new major TYPO3 version shipped with new security features.

TYPO3 v12 provides out-of-the support for sending your website content with a fully customizable Content-Security Policy rule-set based on your templates, your TypoScript and even your plugins and content.

CSP and a CMS: Why is it so complicated?

A major strength of a good CMS is that regular editors — non-coders — can put content on a website, without dealing with HTML, CSS or JavaScript. No training, no technical know-how needed. But as a result: Editors can put any kind of content on a page, like plugins for an image gallery with a zoom functionality based on a JavaScript library. In common scenarios, the security developers need to allow such code for this plugin in the safest way to be allowed in the CSP rules. For this reason, smart CMSes which also deliver frontend rendering unlike a headless CMS  — that's another story — can deal with this by utilizing the framework behind the CMS. TYPO3 v12, with its power to detect usages of a page while generating a page, utilizes all the common CSP features like nonces or hashes for non-cacheable content, unsafe-inline only when marked in a template, directly.

Third-party extensions can provide common patterns of their plugins (such as a Google Maps integration) to hook into the CSP header generation as well.

Disabled on updates, enabled for new sites

TYPO3 provides a strong CSP framework out-of-the-box in TYPO3 v12 - no need to add any extensions or plugins.

As mentioned, enabling CSP on your website might break functionality such as Captcha or a direct integration into a social media post or other dynamic functionality, so it really needs to be battlefield-tested. TYPO3 v12 ships with CSP for the admin interface enabled by default for new sites. However, when upgrading, this feature is disabled, so you don't have to worry about handling CSP during the upgrade. However, you may enable this in v12 during the upgrade or afterwards, to benefit from increased security.

How to enable CSP Headers in TYPO3 Backend

In TYPO3 v12, you can activate sending of CSP Headers for the whole TYPO3 Backend via the Feature Flag `security.backend.enforceContentSecurityPolicy`. If you don’t have any custom extensions with custom Backend modules or enhanced JavaScript or inline CSS, you’re safe by setting the option [SYS][features][security.backend.enforceContentSecurityPolicy] = true in your config/system/settings.php.

If you don’t use any version control or command-line, you can find the toggle in Admin Tools => Settings => Feature Toggles => “Security: backend enforce content security policy”.

Screenshot aus dem TYPO3-Backend (v12) mit Funktionsschaltern zur Aktivierung der CSP-Standardeinstellungen

How to configure CSP headers for the Frontend and per site

Activating CSP headers for the frontend works almost the same. There is a similar toggle [SYS][features][security.frontend.enforceContentSecurityPolicy] = true. For each site, you can individually configure the CSP headers to be sent via a site configuration file “csp.yaml”. ​​For full reference and details see: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/ContentSecurityPolicy/Index.html#site-specific-frontend 

Common Pitfalls & Best Practices

  1. Go from strict to loose
    Ensure that nothing is allowed at first, then browse through your site, your special functionality and plugins to see if everything is working — and loosen your policies where needed instead of having all options allowed.
  2. Analyze and debug
    TYPO3 ships with a new “Content Security Policy” module that reports violations and also shows if the CSP feature for TYPO3 is set up properly.
  3. Use report-only mode
    A report-only mode was added to TYPO3 v12.4.20 with a separate feature flag. https://github.com/TYPO3/typo3/commit/43cb28906c9c8a0d59577f09c9ca0b6660bd44ee which allows to try out stricter rules in production mode.
  4. Monitor your browser console
    The DevTools of your browser console typically log information about CSP violations as well, allowing you to try out stricter rules.
  5. Beware of false positives
    Always look at edge-cases which you cannot fix. As example: Special browsers such as Facebook’s in-app browser inside mobile devices always report CSP violations, because the Facebook App injects JS dynamically, which is — of course — something you want to avoid for your site and users to allow.
  6. Ship good defaults from custom extensions
    Think of all the plugins, inline JavaScript, CSS and Font inclusions in your site rendering and test them in a real browser. Extensions can prepare custom CSP rules which you can include. Have a look at tt_address as an example. https://docs.typo3.org/p/friendsoftypo3/tt-address/main/en-us/Administration/Changelog/v/8-0-0.html#better-csp-support

If you are still curious and want to dig deeper, have a look at TYPO3’s ChangeLog: https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/12.3/Feature-99499-IntroduceContent-Security-PolicyHandling.html

Oliver Hader, the author of the CSP integration in TYPO3 v12, has also created a local environment based on DDEV to see CSP in action “CSP Simulator” https://github.com/ohader/csp-simulator

Conclusion

Setting up TYPO3 with basic CSP support doesn’t need a PHP developer skill, especially for new websites this feature is a must. However, when you update, be sure to enable CSP in report-only mode to find out what you need to adjust before enabling CSP headers for your website.