Problem/Motivation

#2506195: Remove SafeMarkup::set() from Xss::filter() has revealed that we should be relying on the render system's auto-escape and auto-filtering more. If a string is not marked safe then the render system will automatically escape HTML. Therefore calls to SafeMarkup::checkPlain() like:

    $form['admin_label'] = array(
      '#type' => 'item',
      '#title' => $this->t('Block description'),
      '#markup' => Html::escape($definition['admin_label']),
    );

Are unnecessary. Here we could just change #markup to #value and rely on auto-escaping.

The calls to Xss::filterAdmin can be replaced by converting to a render array. For example:

      $variables['types'][$type->id()] = array(
        'type' => $type->id(),
        'add_link' => \Drupal::l($type->label(), new Url('node.add', array('node_type' => $type->id()))),
        'description' => Xss::filterAdmin($type->getDescription()),
      );

We can just do 'description' => array('#markup' => $type->getDescription()), instead because all #markup is auto-filtering for the admin tag list by the render system.

Steps to reproduce

Proposed resolution

Have a look at the code and remove calls that easily be removed.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

CommentFileSizeAuthor
#9 review_all_usages_2527360-9.patch29.36 KBtatarbj

Issue fork drupal-2527360

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

alexpott’s picture

xjm’s picture

Title: Review all usages of Xss::filter(), Xss::filterAdmin(), SafeMarkup::checkPlain() and SafeMarkup::escape() » Review all usages of Xss::filter(), Xss::filterAdmin(), and Html::escape()

 

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tatarbj’s picture

Assigned: Unassigned » tatarbj
Status: Active » Needs work

Hi all,
let me start to work on this issue, seems a good security improvements for core.
Bests,
Balazs.

tatarbj’s picture

Version: 8.4.x-dev » 8.5.x-dev
tatarbj’s picture

Status: Needs work » Needs review
StatusFileSize
new29.36 KB

Here are the 2 scenarios that should be followed in this issue:

1. Xss::filterAdmin() because it calls directly Xss::filter() with the $adminTags. So if we rely on auto-filtering for the admin tag by the render system, we can do that is adviced in the description (to change it to render array).
So the transition is Xss:filterAdmin($whatever) -> ['#markup' => $whatever]

2. When we see the Xss::filter() it can get a parameter with the allowed tags. We can change it with specifically set the #allowed_tags property for the render array. See Render API overview.
So here the transition would be: Xss::filter($whatever, $tags) -> ['#markup' => $whatever, '#allowed_tags' => $tags].

Let me attach a first patch on 8.5.x that makes these changes on non-test classes (and where it makes sense).

I'm still thinking about what's really wrong with Html::escape() as it only triggers a native php function htmlspecialchars(). Anyone could help me to understand why we should also drop them out and how those strings get escaped if we do? (Should be the same pattern followed to use render array for them? It seems a bit weird for me...)

Cheers,
Balazs.

Status: Needs review » Needs work

The last submitted patch, 9: review_all_usages_2527360-9.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

duaelfr’s picture

Assigned: tatarbj » Unassigned

This is quite old!
I was digging into an issue with inline templating within Views and found this piece of code from \Drupal\views\Plugin\views\PluginBase::viewsTokenReplace():

      // Use the unfiltered text for the Twig template, then filter the output.
      // Otherwise, Xss::filterAdmin could remove valid Twig syntax before the
      // template is parsed.

      $build = [
        '#type' => 'inline_template',
        '#template' => $text,
        '#context' => $twig_tokens,
        '#post_render' => [
          function ($children, $elements) {
            return Xss::filterAdmin($children);
          },
        ],
      ];

      // Currently you cannot attach assets to tokens with
      // Renderer::renderInIsolation(). This may be unnecessarily limiting. Consider
      // using Renderer::executeInRenderContext() instead.
      // @todo https://www.drupal.org/node/2566621
      return (string) $this->getRenderer()->renderInIsolation($build);

Here, even if we are using Twig's render engine, filterAdmin is called on post_process without any way to bypass it. In my case, I have an inline template that includes an image field rendered with a responsive style. The <picture> and <srcset> tags are dropped by this post process so I must use an external template instead of the builtin feature of views.

prudloff made their first commit to this issue’s fork.

prudloff’s picture

Issue summary: View changes
Status: Needs work » Needs review

I had a look and only found this call that could easily be removed. But I might have missed some others.

I think several calls have been removed over the years (#2569381: Drupal\views\Plugin\views\area\Result does an unnecessary XSS::adminFilter() for example).

@duaelfr I'm not sure this is related. I think there was some issue about being able to set the list of allowed tags in view templates but I can't find it.

smustgrave’s picture

Not sure I follow why Markup::create(Xss::filterAdmin($element['#value'])); is no longer needed.

xjm’s picture

@smustgrave Re: #26, wrong issue?

smustgrave’s picture

Updated comment sorry!

prudloff’s picture

Not sure I follow why Markup::create(Xss::filterAdmin($element['#value'])); is no longer needed.

#markup already calls Xss::filterAdmin() when it is rendered.

xjm’s picture

A call in the HtmlTag element itself; very nice!

FWIW regarding #22 which I did not read closely before, I think that is works as designed.

xjm’s picture

Is any of #9 forward-portable?

prudloff’s picture

The patch from #9 blindly replaces Xss::filter() calls with a render array, even in places where the expected type is a string.
For example:

-    $safe_string->string = Html::normalize(Xss::filter($string, static::allowedTags()));
+    $safe_string->string = Html::normalize(['#markup' => $string, '#allowed_tags' => static::allowedTags()]);

This would definitely not work.

Which is why I did not use it as basis for the MR and started from scratch.

xjm’s picture

Ah good call; I did not actually review it. Thanks @prudloff.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update

Trying to catch up on issues that have been in review for a while.

Can we update the summary with what was done to determine this was the only spot? Was it a search?

If only 1 may be worth a title update as well.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.