One of the security principles is sanitizing strings and variables passed from client to server. In plain PHP there are some functions to prevent XSS (Cross-site Scripting) vulnerabilities:

What is Drupal 8 strategy to prevent XSS attacks? How can I clean up client data post to protect my site from XSS attacks?

I remember Drupal 7 has filter_xss() to prevent XSS vulnerabilities, but what is Drupal 8 strategy against XSS vulnerabilities?

  • Also, look into defining a Content-Security-Policy header for your site, as an additional layer of XSS protection (drupal.org/project/csp). Unfortunately Drupal 8 is not yet able to block inline scripts completely due to it use of CKEditor 4, but recent updates to the CSP spec will at least allow narrowing which inline scripts are allowed once adopted by browsers.
    – gapple
    Feb 2, 2019 at 9:03

3 Answers 3


Sanitizing on output to avoid Cross Site Scripting (XSS) attacks

Use Twig templates The Twig theme engine now auto escapes everything by default. That means that every string printed from a Twig template (e.g. anything between {{ }}) gets automatically sanitized if no filters are used.

See Filters - Modifying Variables In Twig Templates for the Twig filters available in Drupal.

In order to take advantage of Twig’s automatic escaping (and avoid safe markup being escaped) ideally all HTML should be outputted from Twig templates.

API functions Use t() and \Drupal::translation()->formatPlural() with @ or % placeholders to construct safe, translatable strings. See Code text translation API in Drupal 8 for more details.

Strings sanitized by t(), Html::escape(), Xss::filter() or Xss::filterAdmin() are automatically marked safe, as are markup strings created from render arrays via Renderer.

While it can also sanitize text, it's almost never correct to use check_markup in a theme or module except in the context of something like a text area with an associated text format.

Source: Drupal 8: Writing secure code by: Rade, Shyamala, Robert Castelo, and Pere Orga.


Drupal generally takes the approach of filtering on output, not on input.

A module which accepts a person's input as not part of the field system must filter it when it outputs it (even from privileged, administrator users). Output is usually a render array. So a simple way to do this is to limit allowed tags on render. To take an example from taxonomy module's output of a term label:

use Drupal\Component\Utility\Xss;


  public function termTitle(TermInterface $taxonomy_term) {
    return [
      '#markup' => $taxonomy_term->getName(),
      '#allowed_tags' => Xss::getHtmlTagList(),

Twig templates did not sanitize output in my application. A script string or XSS attack entered into a comment field and saved was executed when the page loaded. Instead, I solved the problem by sanitizing each string input field in hook_ENTITY_TYPE_load.

 if(isset($entity->$fieldName)) {  
        $value = $entity->get($fieldName)->value;  
        $value =  htmlspecialchars($value);  
        $entity->set($fieldName, $value);  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.