Issue metadata
Sign in to add a comment
|
Security: Same-name function declaration can overwrite window.location in Chrome 50+
Reported by
tyh1k....@gmail.com,
Dec 2 2016
|
||||||||||||||||||||||
Issue description
VULNERABILITY DETAILS
In Chrome 50+, users can overwrite window.location or other built-in objects by
using a same-name function declaration in global context. It leads to potential
security problems if malicious scripts use this to do some fishing, redirection
or other things.
It is easy to reproduce, only one line: function location(){};
VERSION
Chrome Version: [54.0.2840.98 (64-bit)] + [stable], also seen in 50.0.2661.102
Operating System: [OS X EI Capitan 10.11.3 (15D21)], also seen in windows
REPRODUCTION CASE
Open location.html in attachment, open development tools and switch to console,
execute location.href = 'http://www.google.com' and you will see an alert pops up.
execute navigator.userAgent you will get a "fake ua" instead of real one.
,
Dec 2 2016
Thanks for the report. Unless I'm misunderstanding something, this override doesn't cross origin boundaries right? haraken, could you please take a look, or help with assigning this to a more suitable person? Thanks.
,
Dec 3 2016
,
Dec 3 2016
I think since it's an implementation issue, not a resource request, there is no cross-origin constraint for it. Any script in the webpage can override it, including those cross-origin scripts. Did i get it wrong about the "cross origin boundaries" ?
,
Dec 3 2016
,
Dec 5 2016
As far as I tested, there is no leak over origins. However, when 'location' is overwritten, crossOriginWin.location is no longer accessible (throws a SecurityError) despite it should be a cross-origin accessible attribute.
,
Dec 5 2016
jochen@, could you tell us if V8 supports the following situation (data property + unconfigurable + readonly + [PutForwards])?
a) window.location is a data property with C++ callbacks for get and set.
b) window.location is [Unforgeable] / configurable:false.
c) window.location is [PutForwards] and readonly.
window.location is currently implemented as:
v8::AccessControl = v8::ALL_CAN_READ |
v8::ALL_CAN_WRITE |
v8::PROHIBITS_OVERWRITING
v8::PropertyAttribute = v8::DontDelete
and it's possible to define a function named "location" probably because the property looks writable. A new function "location" overwrites the existing "location" attribute.
I know that V8 supports data property + readonly + [Replaceable] if Blink doesn't set the "set" callback (i.e. making the property writable without the "set" callback).
[Replaceable] readonly data property is implemented as:
v8::AccessControl = v8::ALL_CAN_READ
v8::PropertyAttribute = v8::DontDelete |
v8::ReadOnly
without "set" callback.
However, is there a good way to support [PutForwards] readonly data property?
,
Dec 5 2016
Or is it possible that, when a new function is defined, V8 checks if there already exists a property with the same name and if it's configurable or not?
,
Dec 5 2016
@yukishiino Thanks for the detailed description, now I can understand the cross origin boundaries you said before. So it leads to the fact that the top window lost control over the location of cross-origin frames or windows, am i right? I myself did not noticed that before.
,
Dec 5 2016
,
Dec 5 2016
,
Dec 5 2016
,
Dec 5 2016
re #c9 , the fact is that a function named "location" shadows the window.location attribute from all the windows including iframes regardless of whether it's same origin or cross origin.
,
Dec 5 2016
@yukishiino Ok, I think i've got it right. Thanks for your explanation.
,
Dec 7 2016
Friendly ping? Assigned to franzih@. Assign back to me if there is something Blink can fix.
,
Dec 7 2016
Could you make window.location ReadOnly rather than DontDelete?
,
Dec 9 2016
Unfortunately v8::ReadOnly doesn't work as expected in this case.
case a) v8::PropertyAttribute = v8::ReadOnly
a-1) You can still define "function location() {}".
a-2) You can delete window.location (shouldn't be deletable).
a-3) window.location="http://new/location" doesn't make any navigation (should navigate).
case b) v8::PropertyAttribute = v8::DontDelete | v8::ReadOnly
b-1) You can still define "function location() {}".
b-2) OK: You cannot delete window.location.
b-3) window.location="http://new/location" doesn't make any navigation (should navigate).
case c) v8::PropertyAttribute = v8::DontDelete
c-1) You can still define "function location() {}".
c-2) OK: You cannot delete window.location.
c-3) OK: window.location="http://new/location" makes a navigation.
In all cases, we can still define a function with name="location".
For the deletion/configurability ([Unforgeable]) and navigation ([PutForwards=href]), v8::ReadOnly doesn't work as expected.
,
Dec 13 2016
I see. The setter is not invoked for declarations. I'll check if we can fix that.
,
Dec 15 2016
The following revision refers to this bug: https://chromium.googlesource.com/v8/v8.git/+/0e7a2ca0d75fad836435b0836ccc13c2b128e2f3 commit 0e7a2ca0d75fad836435b0836ccc13c2b128e2f3 Author: franzih <franzih@chromium.org> Date: Thu Dec 15 14:41:07 2016 [runtime] Throw if re-declaring a non-configurable accessor. If an accessor property is non-configurable, one should not be able to re-declare it as a function. This specifically applies to special properties like window.location. BUG= chromium:670596 Review-Url: https://codereview.chromium.org/2582493002 Cr-Commit-Position: refs/heads/master@{#41725} [modify] https://crrev.com/0e7a2ca0d75fad836435b0836ccc13c2b128e2f3/src/runtime/runtime-scopes.cc [modify] https://crrev.com/0e7a2ca0d75fad836435b0836ccc13c2b128e2f3/test/cctest/test-api-accessors.cc
,
Dec 15 2016
,
Dec 16 2016
,
Mar 24 2017
This bug has been closed for more than 14 weeks. Removing security view restrictions. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by elawrence@chromium.org
, Dec 2 2016