Problem/Motivation
Discovered whilst working on #2780285: XSS in date format configuration. In converting part of \Drupal\system\Tests\System\DateTimeTest to JavascriptTestBase I discovered that the following code has a problem:
$this->assertEscaped("<script>alert('XSS');</script>", 'The date format was properly escaped');
Eventually this code ends up doing:
>>> \Drupal\Component\Utility\Html::escape("<script>alert('XSS');</script>");
=> "<script>alert('XSS');</script>"
The problem is that ' is converted to ' by the browser and is never present in the raw response.
Proposed resolution
Remaining tasks
User interface changes
None
API changes
None
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#24 | 2780475-2-24.patch | 10.42 KB | alexpott |
#24 | 23-24-interdiff.txt | 4.92 KB | alexpott |
#23 | 2780475-2-23.patch | 7.99 KB | alexpott |
#19 | 2780475-19.patch | 7.8 KB | jofitz |
#14 | 2780475-14.patch | 7.68 KB | alexpott |
Comments
Comment #2
alexpottComment #3
alexpottComment #4
alexpottHere's some tests that show the problem - I've also added a test to BrowserTestBaseTest to prove we don't have a problem there.
Comment #5
alexpottIn the javascript test the single and double quotes are not the characters returned by Html::escape()... Here's what we see...
Comment #7
alexpottHere's a patch that fixes it but discovers another problem with risky test identification for JavascriptTestBase tests.
Comment #8
alexpottOk so all tests that install a module have an assertion so the risky test thing is hard to trigger. Here's a simple solution to the problem here.
Comment #9
alexpottLet's make the test more explicit and more separated so there's no chance of something unexpected occurring.
Comment #10
mpdonadioThis looks pretty good, but I would want to look at this when I get home on my dev machine so I can see the test run in place.
Looks like the assertions need to check for a div instead of a p element?
Comment #11
alexpottNice spot @mpdonadio - negative assertions should always be backed up by a positive one.
Comment #12
dawehnerDon't we have the same problem over in BTBT as well?
Comment #14
alexpott@dawehner good point.
Comment #15
mpdonadioI think this looks nice. Few questions / comments.
Would
$assert->assertEscaped('Escaped: <"\'&>');
be a safer test in case those characters are in the response escaped, for whatever reason?I think we need a reference here. I cannot find anything about this behavior anywhere with Mink or PhantomJS.
Comment #18
mpdonadio#14 doesn't apply anymore.
Comment #19
jofitz CreditAttribution: jofitz at ComputerMinds commentedRe-rolled.
Comment #23
alexpottRerolled.
Comment #24
alexpottThanks for the review @mpdonadio. I agree with #15.1 - changed that.
Re #15.2 I can't find a thing to point to but we have test coverage of what's happening so if they change it then we've got it covered. This is not on the Mink level. It's below that. It's in the how the webdriver implementation returns the content of the page. If you look at the value return by the div we're interesting in looks like this:
<div class="escaped">Escaped: <"'&></div>
- \Behat\Mink\Driver\Selenium2Driver::getContent(). There's no manipulation on the PHP level. I've looked in the webdriver spec and this is not mentioned either. There's nothing in the spec.Comment #26
mpdonadioLooks ready for prime time.
Comment #28
catchNit: them them (fixed on commit).
Committed 1d0a07f and pushed to 8.8.x. Thanks!
Comment #29
catchAnd cherry-picked to 8.7.x, thanks!