Problem/Motivation
@mpdonadio, the DateTime subsystem maintainer, discovered an exploitable XSS situation in the date formats configuration.
This vulnerability can be fixed publicly (and not at https://security.drupal.org/node/add/project-issue/drupal) as per http://drupal.org/security-advisory-policy because it requires the compromised account to have an advanced permission that already makes the site compromised.
Steps to create in 8.1.8:
- Visit admin/config/regional/date-time
- Add a format
- Name the format XSS, and for the format string use "c -- \<\s\c\r\i\p\t\>\a\l\e\r\t\(\'\f\o\o\'\)\<\/\s\c\r\i\p\t\>" without the double quotes
- Note that you should have gotten one or more alerts
- Save the format
- Edit the format, admin/config/regional/date-time/formats/manage/xss
- Note that you should have gotten the alert
This would allow an admin to add XSS to a date format. If another admin edits the format, they will get the XSS exploit.
He is still evaluating whether this is exploitable elsewhere date formats are used, or in 8.2.x. He is not seeing any other places he has tested (like with the DateTime widgets for formatters).
Proposed resolution
The output of date formats is not trusted in Drupal 8 and there are several tests about this - see \Drupal\system\Tests\Common\FormatDateTest::testFormatDate and \Drupal\system\Tests\System\DateTimeTest::testDateFormatConfiguration. The problem here is dateFormatHandler in system.date.js which does $preview.html(dateString); which trusts the dateString.
Remaining tasks
User interface changes
None
API changes
None
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#28 | 2780285-2-28.patch | 3.26 KB | alexpott |
#28 | 2780285-2-28.test-only.patch | 2.35 KB | alexpott |
#28 | 27-28-interdiff.txt | 1.64 KB | alexpott |
#27 | 2780285-2-27.patch | 2.98 KB | alexpott |
#27 | 2780285-2-27.test-only.patch | 2.07 KB | alexpott |
Comments
Comment #3
alexpottComment #4
alexpottNote the docs say that the output is not to be trusted AND in Drupal 8 this string is not marked safe so it will be auto-escaped by default see
\Drupal\Core\Datetime\DateFormatterInterface::format()
Comment #5
alexpottComment #6
mpdonadioThe problem also exists in D7. There, the problem happens both on the format listing page (admin/config/regional/date-time/formats) and the entry page. On the listing page, the input is displayed unsanitized, so
fixes that. Haven't gotten done tracing through the JS section.
Comment #7
mpdonadioDidn't mean to remove that file. I thought it was the patch I had uploaded...
Using .text() accomplished instead of .html() accomplishes the same thing.
Comment #8
mpdonadio@alexpott and I had a quick conversation about this in IRC. He had the idea to move DateTimeTest::testDateFormatConfiguration to a JavascriptTestBase so we can adequately test the identified vector.
I went through the existing test coverage, usages, and did a lot of manual testing with this, and am pretty sure this is limited just to the JS preview on date format add/edit.
Comment #9
YesCT CreditAttribution: YesCT commentedComment #10
YesCT CreditAttribution: YesCT commentedclarifying in the issue that this can be a public issue
Comment #11
alexpottDiscovered #2780475: assertEscaped() and assertUnescaped don't work as you would expect in JavascriptTestBase whilst working on the test. The test will fail because of it. Also the test does not yet test for the error reported in the issue summary it is just a conversion.
Comment #13
catchBumping priority since this is still not a nice bug.
Comment #14
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedI think for Drupal 7 this might be handled by #1892640: XSS in date formats admin page (an older issue which was committed to Drupal 8 but still needs to be backported to Drupal 7).
Comment #15
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedCross-post.
Comment #17
th_tushar CreditAttribution: th_tushar commentedAttached is the patch to fix this issue.
Comment #19
alexpott@th_tushar the fix in #11 is the one we want - how come you ignored the prior work on this issue? Atm we're blocked on #2780475: assertEscaped() and assertUnescaped don't work as you would expect in JavascriptTestBase
Comment #22
mpdonadioBlocked per #19 on #2780475: assertEscaped() and assertUnescaped don't work as you would expect in JavascriptTestBase.
Comment #26
alexpottThe blocker is in.
Comment #27
alexpottrerolled. Decided not to convert all of \Drupal\Tests\system\Functional\System\DateTimeTest::testDateFormatConfiguration() to javascript testing - way too much change.
Comment #28
alexpottWhoops... the test doesn't fail... this one does.
Comment #30
mpdonadioChange and test looks good.
Comment #32
larowlanCommitted c4a7d0c and pushed to 8.8.x. Thanks!
c/p to 8.7.x