Title: [205297] trunk
Revision
205297
Author
[email protected]
Date
2016-09-01 10:48:25 -0700 (Thu, 01 Sep 2016)

Log Message

Align cross-origin proto getter / setter behavior with the specification
https://bugs.webkit.org/show_bug.cgi?id=161455

Reviewed by Mark Lam.

Source/_javascript_Core:

Align cross-origin proto getter / setter behavior with the specification:

The setter should throw a TypeError:
- https://html.spec.whatwg.org/#windowproxy-setprototypeof
- https://html.spec.whatwg.org/#location-setprototypeof
- https://tc39.github.io/ecma262/#sec-object.setprototypeof (step 5)

The getter should return null:
- https://html.spec.whatwg.org/#windowproxy-getprototypeof
- https://html.spec.whatwg.org/#location-getprototypeof

I have verified that this aligns our behavior with Firefox and Chrome.

* runtime/JSGlobalObjectFunctions.cpp:
(JSC::GlobalFuncProtoGetterFunctor::operator()):
(JSC::globalFuncProtoSetter):

LayoutTests:

Add layout test coverage.

* http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt:
* http/tests/security/cross-frame-access-object-getPrototypeOf.html:
* http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt:
* http/tests/security/cross-frame-access-object-setPrototypeOf.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (205296 => 205297)


--- trunk/LayoutTests/ChangeLog	2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/ChangeLog	2016-09-01 17:48:25 UTC (rev 205297)
@@ -1,3 +1,17 @@
+2016-09-01  Chris Dumez  <[email protected]>
+
+        Align cross-origin proto getter / setter behavior with the specification
+        https://bugs.webkit.org/show_bug.cgi?id=161455
+
+        Reviewed by Mark Lam.
+
+        Add layout test coverage.
+
+        * http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt:
+        * http/tests/security/cross-frame-access-object-getPrototypeOf.html:
+        * http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt:
+        * http/tests/security/cross-frame-access-object-setPrototypeOf.html:
+
 2016-09-01  Ryan Haddad  <[email protected]>
 
         Marking media/video-main-content-allow-then-scroll.html as flaky on ios-simulator-wk2.

Modified: trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt (205296 => 205297)


--- trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt	2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt	2016-09-01 17:48:25 UTC (rev 205297)
@@ -1,9 +1,13 @@
 CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
 CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
+CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
+CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
 This tests that you can't get the prototype of the window or history objects cross-origin using Object.getPrototypeOf().
 
 PASS: Object.getPrototypeOf(targetWindow) should be 'null' and is.
 PASS: Object.getPrototypeOf(targetWindow.location) should be 'null' and is.
+PASS: protoGetter.call(targetWindow) should be 'null' and is.
+PASS: protoGetter.call(targetWindow.location) should be 'null' and is.
 PASS targetWindow.history threw exception SecurityError (DOM Exception 18): Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match..
 PASS: successfullyParsed should be 'true' and is.
 

Modified: trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf.html (205296 => 205297)


--- trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf.html	2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf.html	2016-09-01 17:48:25 UTC (rev 205297)
@@ -18,6 +18,10 @@
 
             shouldBeNull("Object.getPrototypeOf(targetWindow)");
             shouldBeNull("Object.getPrototypeOf(targetWindow.location)");
+            protoGetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').get;
+            shouldBeNull("protoGetter.call(targetWindow)");
+            shouldBeNull("protoGetter.call(targetWindow.location)");
+
             shouldThrowErrorName("targetWindow.history", "SecurityError");
 
             finishJSTest();

Modified: trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt (205296 => 205297)


--- trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt	2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt	2016-09-01 17:48:25 UTC (rev 205297)
@@ -1,5 +1,7 @@
 CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
 CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
+CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
+CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
 This tests that you can't set the prototype of the window or location objects cross-origin using Object.setPrototypeOf()
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -11,6 +13,12 @@
 PASS: targetWindow.location instanceof Array should be 'false' and is.
 PASS Object.setPrototypeOf(targetWindow.location, Array.prototype) threw exception TypeError: Permission denied.
 PASS: targetWindow.location instanceof Array should be 'false' and is.
+PASS: targetWindow instanceof Array should be 'false' and is.
+PASS protoSetter.call(targetWindow, Array.prototype) threw exception TypeError: Permission denied.
+PASS: targetWindow instanceof Array should be 'false' and is.
+PASS: targetWindow.location instanceof Array should be 'false' and is.
+PASS protoSetter.call(targetWindow.location, Array.prototype) threw exception TypeError: Permission denied.
+PASS: targetWindow.location instanceof Array should be 'false' and is.
 PASS: successfullyParsed should be 'true' and is.
 
 TEST COMPLETE

Modified: trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf.html (205296 => 205297)


--- trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf.html	2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf.html	2016-09-01 17:48:25 UTC (rev 205297)
@@ -24,6 +24,15 @@
             shouldThrowErrorName("Object.setPrototypeOf(targetWindow.location, Array.prototype)", "TypeError");
             shouldBeFalse("targetWindow.location instanceof Array");
 
+            protoSetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
+            shouldBeFalse("targetWindow instanceof Array");
+            shouldThrowErrorName("protoSetter.call(targetWindow, Array.prototype)", "TypeError");
+            shouldBeFalse("targetWindow instanceof Array");
+
+            shouldBeFalse("targetWindow.location instanceof Array");
+            shouldThrowErrorName("protoSetter.call(targetWindow.location, Array.prototype)", "TypeError");
+            shouldBeFalse("targetWindow.location instanceof Array");
+
             finishJSTest();
         }
     </script>

Modified: trunk/Source/_javascript_Core/ChangeLog (205296 => 205297)


--- trunk/Source/_javascript_Core/ChangeLog	2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-09-01 17:48:25 UTC (rev 205297)
@@ -1,3 +1,27 @@
+2016-09-01  Chris Dumez  <[email protected]>
+
+        Align cross-origin proto getter / setter behavior with the specification
+        https://bugs.webkit.org/show_bug.cgi?id=161455
+
+        Reviewed by Mark Lam.
+
+        Align cross-origin proto getter / setter behavior with the specification:
+
+        The setter should throw a TypeError:
+        - https://html.spec.whatwg.org/#windowproxy-setprototypeof
+        - https://html.spec.whatwg.org/#location-setprototypeof
+        - https://tc39.github.io/ecma262/#sec-object.setprototypeof (step 5)
+
+        The getter should return null:
+        - https://html.spec.whatwg.org/#windowproxy-getprototypeof
+        - https://html.spec.whatwg.org/#location-getprototypeof
+
+        I have verified that this aligns our behavior with Firefox and Chrome.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::GlobalFuncProtoGetterFunctor::operator()):
+        (JSC::globalFuncProtoSetter):
+
 2016-09-01  Csaba Osztrogonác  <[email protected]>
 
         Unreviewed ARM buildfix after r205283.

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (205296 => 205297)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2016-09-01 17:48:25 UTC (rev 205297)
@@ -887,6 +887,8 @@
 
         if (m_thisObject->allowsAccessFrom(visitor->callFrame()))
             m_result = JSValue::encode(m_thisObject->getPrototype(m_exec->vm(), m_exec));
+        else
+            m_result = JSValue::encode(jsNull());
 
         return StackVisitor::Done;
     }
@@ -974,8 +976,10 @@
     if (!thisObject)
         return JSValue::encode(jsUndefined());
 
-    if (!checkProtoSetterAccessAllowed(exec, thisObject))
+    if (!checkProtoSetterAccessAllowed(exec, thisObject)) {
+        throwTypeError(exec, scope, ASCIILiteral("Permission denied"));
         return JSValue::encode(jsUndefined());
+    }
 
     // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
     if (!value.isObject() && !value.isNull())
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to