New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 670596 link

Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Dec 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 1
Type: Bug-Security



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.


 
location.html
1.1 KB View Download
Components: Blink>Bindings
Microsoft Edge throws a script error: "SCRIPT5078: Cannot redefine non-configurable property 'location'"

Firefox 53 throws a script error: "TypeError: cannot declare global binding `location': property must be configurable or both writable and enumerable"
Labels: Security_Severity-Low Security_Impact-Stable OS-All
Owner: haraken@chromium.org
Status: Assigned (was: Unconfirmed)
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.
Cc: haraken@chromium.org
Owner: yukishiino@chromium.org
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" ?
Project Member

Comment 5 by sheriffbot@chromium.org, Dec 3 2016

Labels: Pri-2
Labels: -Pri-2 Pri-1
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.

Cc: jochen@chromium.org
Components: Blink>JavaScript>API
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?

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?

@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.
Cc: verwa...@chromium.org
Cc: hablich@chromium.org
Cc: fran...@chromium.org
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.
@yukishiino
Ok, I think i've got it right. 
Thanks for your explanation. 
Cc: yukishiino@chromium.org
Owner: fran...@chromium.org
Friendly ping?

Assigned to franzih@.  Assign back to me if there is something Blink can fix.
Could you make window.location ReadOnly rather than DontDelete? 
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.

Status: Started (was: Assigned)
I see. The setter is not invoked for declarations. I'll check if we can fix that.
Project Member

Comment 19 by bugdroid1@chromium.org, 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

Status: Fixed (was: Started)
Project Member

Comment 21 by sheriffbot@chromium.org, Dec 16 2016

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
Project Member

Comment 22 by sheriffbot@chromium.org, Mar 24 2017

Labels: -Restrict-View-SecurityNotify allpublic
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