Follow-up to #2510104: Convert drupalSettings from JavaScript to JSON, to allow for CSP in the future
Problem/Motivation
The current selector for the drupalSettings is:
var settingsElement = document.querySelector('script[type="application/json"][data-drupal-selector="drupal-settings-json"]');
This means that when someone manages to place some drupalSettings on the page by exploiting XSS they could with CSP on manipulate settings, which could potentially lead to a real XSS exploit. (provided the drupalSettings are in the footer)
Proposed resolution
Use a selector as true child of head or body instead:
var settingsElement = document.querySelector('head > script[type="application/json"][data-drupal-selector="drupal-settings-json"], body > script[type="application/json"][data-drupal-selector="drupal-settings-json"]');
e.g. While before this patch with CSP enabled someone could e.g. put a script element into a hypothetical non-secure page-title element (via some buggy contrib module), which would be at:
content > div.main-region > span.page-title
After this patch, this exploit vector no longer works as it is way harder to manipulate something that is a direct child of BODY or HEAD.
Remaining tasks
- Create patch
- Commit
User interface changes
- None
API changes
- None
RC phase evaluation
- - Category: Task, because it is security hardening
- - Priority: Major, because it is security hardening
- - Prioritized changes: Security
- - Disruption: None, as it is just the selector that is changed and other selectors will continue to work.
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | harden_drupalsettings-2592925-19.patch | 748 bytes | fabianx |
| #19 | interdiff.txt | 610 bytes | fabianx |
Comments
Comment #2
sagar ramgade commentedPatch attached.
Comment #3
fabianx commentedThanks for the patch!
There is a slight space change that needs to be fixed.
--
Assigning to nod_ for review.
Comment #4
droplet commentedIt's like better but useless. anyone able to insert a "script" tag, they could inject settings in many way. I'd say close as won't fix and KISS.
Comment #5
pere orgaUnless CSP is enabled. Then JavaScript code inside script tags would not run, but settings could still be injected that way.
The reason I would close this is because document.querySelector() returns the first element within the document, so the patch would not make much difference.
Comment #6
fabianx commented#5: Oh, yes it would.
Settings are usually at the bottom of the body by now, so someone could inject settings that way - in case of XSS and CSP enabled and given our Drupal.ajax structure I am pretty sure settings are enough to exploit this somehow.
Comment #7
fabianx commentedClarifying title ...
Comment #8
droplet commentedUmm. make sense.
Comment #9
pere orgaAh, if Drupal settings are in the bottom then yes.
Comment #10
nod_At a high level we're in the same situation with D7. anything can add a script tag that messes with
Drupal.settingsvalue.If we take the initial scenario:
If someone manage to place some drupalSettings on the page, it means they managed to put a script tag on the page (whatever the type attribute is) and if that's the case, all bets are off. We can't do anything to salvage the situation.
The only thing we could do is make drupalsettings an inline script again and add the CSP header + attribute needed: http://www.html5rocks.com/en/tutorials/security/content-security-policy/... short of that I'd vote for a won't fix on this issue.
Comment #11
fabianx commented#10: Huh?
If CSP is enabled and someone manages to put a script tag on the page, it usually is in a deeper down level as only very very few things directly are below BODY or HEAD elements.
So why would this direct-child-of-body-or-head selector not harden the security on that?
Comment #12
nod_Doesn't hurt and it does prevent potential issues when CSP is on. I sort of missed the point in #10.
NW only because of whitespace. RTBC otherwise.
Comment #13
fabianx commentedUpdated IS and added RC evaluation.
Comment #14
fabianx commentedFixed whitespace and added some docs so someone is not "simplifying" this in the future.
Comment #15
nod_all good
Comment #16
catchTagging as RC target after discussing with the other committers.
However no need to self-reference this issue in the comment, git blame (or an explanation) is better.
Comment #17
fabianx commentedHere we go with the self-reference removed.
Comment #18
wim leersI think there's a typo? Perhaps I'm just tired.
s/harden XSS exploits/harden against XSS exploits/
Can be fixed on commit either way; all committers are native English speakers :P
Comment #19
fabianx commentedUhm, ... Thanks! Nice catch :p.
Fixed in attached patch.
Comment #20
catchCommitted/pushed to 8.0.x, thanks!