Problem/Motivation

A FILTER_MODE_BLACKLIST was added to the Xss class. To call this dangerous is a serious understatement. People might get confused as to which one to use and a flawed call coupled with blacklist is a sechole. With the traditional whitelist, there is much less confusion and you need to straightforward enable insecure tags.

Proposed resolution

  1. Remove FILTER_MODE_BLACKLIST from the Core namespace. Nuke it from orbit. Have you guys completely lost your mind?? One bad call to this and your site is toast.
  2. Make Drupal\editor\EditorXssFilter\Standard extend Xss
  3. Factor out if (!isset($html_tags[strtolower($elem)])) into a method.
  4. Override method

Remaining tasks

User interface changes

API changes

The optional $mode argument is gone from Filter::Xss. Good riddance. Change notice at https://www.drupal.org/node/2365293

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

chx’s picture

Issue summary: View changes
Status: Needs review » Active
FileSize
5.29 KB
chx’s picture

Status: Active » Needs review
chx’s picture

Issue summary: View changes
chx’s picture

FileSize
5.3 KB

The last submitted patch, blacklist_mad.patch, failed testing.

The last submitted patch, 1: 2364647_1.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 4: 2364647_2.patch, failed testing.

Wim Leers’s picture

One bad call to this and your site is toast.

Yes, calling it incorrectly will lead to security problems. Just like forgetting to call Xss::filter() at all will lead to security problems.

Your proposal sounds fine though — as long as the logic continues to work in the same way (i.e. functionally equivalent), I'm fine with that.

chx’s picture

Status: Needs work » Needs review
FileSize
5.83 KB
Fabianx’s picture

Status: Needs review » Reviewed & tested by the community

RTBC, the proposal looks great to me.

Thanks chx for reminding us that by providing insecure APIs, they will be used in strange ways.

Secure-by-default FTW!

dawehner’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/editor/src/EditorXssFilter/Standard.php
diff --git a/core/tests/Drupal/Tests/Component/Utility/XssTest.php b/core/tests/Drupal/Tests/Component/Utility/XssTest.php
index 7f45b17..7665f7c 100644

index 7f45b17..7665f7c 100644
--- a/core/tests/Drupal/Tests/Component/Utility/XssTest.php

--- a/core/tests/Drupal/Tests/Component/Utility/XssTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/XssTest.php

+++ b/core/tests/Drupal/Tests/Component/Utility/XssTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/XssTest.php
@@ -10,6 +10,7 @@

@@ -10,6 +10,7 @@
 use Drupal\Component\Utility\Xss;
+use Drupal\editor\EditorXssFilter\Standard;
 use Drupal\Tests\UnitTestCase;
 
 /**

@@ -462,7 +463,7 @@ public function providerTestFilterXssNotNormalized() {
    */
   public function testBlacklistMode($value, $expected, $message, array $disallowed_tags) {
-    $value = Xss::filter($value, $disallowed_tags, Xss::FILTER_MODE_BLACKLIST);
+    $value = Standard::filter($value, $disallowed_tags);
     $this->assertSame($expected, $value, $message);
   }

I think chx did not wanted to already RTBC this issue.

We do have a compser.json as part of Drupal\Component\Utility so we should ensure that our tests don't rely on some module code,
or in other words you can't really commit and issue which still has remaining tasks :)

chx’s picture

Yeah, it's not ready for sure, look at the IS, lists remaining tasks. 1) and 2) is technical and easy. 3) is not so easy although it shouldn't block this patch.

dawehner’s picture

@chx
Idealy 3) should be a blocker in general, as it has shown a clear problem in our process.

Fabianx’s picture

Woops, sorry. I missed that part in the IS. Thanks, dawehner.

chx’s picture

Issue summary: View changes
FileSize
12.12 KB

Now it should be ready. Doxygen added, test moved (and I ran both locally). As for fixing our process, I have no idea.

chx’s picture

Issue summary: View changes
FileSize
12.1 KB

1 character doxygen fix. Also, 4 files changed, 94 insertions(+), 97 deletions(-) the patch is net negative while significantly more secure. Sigh.

Fabianx’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Security improvements

I could not find anything problematic here, the patch looks good. Test coverage is the same and applies to its own scope => RTBC

Wim Leers’s picture

Patch looks good.

alexpott queued 16: 2364647_16.patch for re-testing.

alexpott’s picture

For some reason Drupal\Tests\editor\Unit\EditorXssFilter\StandardTest does not pass locally for me - sending back for a retest.

chx’s picture

➜  core git:(8.0.x) ✗ phpunit **/EditorXssFilter/StandardTest.php
PHPUnit 4.1.4 by Sebastian Bergmann.

Configuration read from /home/chx/www/d8/core/phpunit.xml.dist

...............................................................  63 / 191 ( 32%)
............................................................... 126 / 191 ( 65%)
............................................................... 189 / 191 ( 98%)
..

Time: 1.95 seconds, Memory: 9.50Mb

OK (191 tests, 191 assertions)

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 16: 2364647_16.patch, failed testing.

Status: Needs work » Needs review

alexpott queued 16: 2364647_16.patch for re-testing.

alexpott’s picture

Status: Needs review » Reviewed & tested by the community

I broke HEAD - that has nothing to do with my local fails unfortunately. Investigating.

dawehner’s picture

+1

alexpott’s picture

So this is a php version thing.

PHP 5.5.8 (cli) (built: Jan 12 2014 18:50:29) fails
PHP 5.5.18 (cli) (built: Oct 19 2014 15:32:33) passes

Wim Leers’s picture

I've been working with 5.5.11 for many months now. So this must be something that's changed in PHP in version 5.5.12 or later. Looking at the changelog now.

Wim Leers’s picture

Wim Leers’s picture

Disregard #27 and #28; apparently HEAD works fine with 5.5.18, it's specifically this patch that triggers a failure on 5.5.18. I'm now betting it's late static binding, because that's the only noteworthy change here.

alexpott’s picture

PHP 5.4.24 (cli) (built: Jan 12 2014 18:13:14) fails too
PHP 5.6.0alpha1 (cli) (built: Jan 24 2014 09:16:15) fails

PHP 5.4.34 (cli) (built: Oct 19 2014 15:13:21) passes
PHP 5.6.2 (cli) (built: Oct 19 2014 15:53:04) passes

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Looks like https://bugs.php.net/bug.php?id=66622 is catching us.

    $splitter = function ($matches) use ($html_tags) {
      return static::split($matches[1], $html_tags);
    };
Fabianx’s picture

We should run our unit tests through travis-ci to test on more PHP versions? (but that is really off-topic - follow-up?)

chx’s picture

Assigned: Wim Leers » chx
catch’s picture

Title: [sechole] Filter:XSS has an insane blacklist mode » [sechole] Remove blacklist mode from Filter:XSS
dawehner’s picture

Did someone verified whether self:: works here without problems? The amount of usecases to override just that particular method is pretty low to be honest.

alexpott’s picture

Status: Needs work » Needs review
FileSize
2.27 KB
12.81 KB

This fixes the issue by kind of doing our own late static binding. Tested on PHP 5.5.8 and 5.5.18 - works a treat.

Fabianx’s picture

Status: Needs review » Reviewed & tested by the community

A very nice idea! :)

Back to RTBC

catch’s picture

Status: Reviewed & tested by the community » Fixed

This looks good and the workaround for the static binding/anon function issue is both nifty and self-contained.

Committed/pushed to 8.0.x, thanks!

  • catch committed 89b4f96 on 8.0.x
    Issue #2364647 by chx, alexpott: Fixed [sechole] Remove blacklist mode...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

quietone’s picture

Publish the change record.