- Revision
- 202151
- Author
- [email protected]
- Date
- 2016-06-16 18:10:08 -0700 (Thu, 16 Jun 2016)
Log Message
Restrict security origin inheritance to empty, about:blank, and about:srcdoc URLs
https://bugs.webkit.org/show_bug.cgi?id=158855
<rdar://problem/26142632>
Reviewed by Alex Christensen.
Source/WebCore:
Tests: http/tests/dom/window-open-about-blank-and-access-document.html
http/tests/dom/window-open-about-webkit-org-and-access-document.html
Document.cpp previously checked whether a document should inherit its owner's
security origin by checking if the URL is either empty or blank. URL.cpp in
turn only checks if the protocol is "about:" in the isBlankURL() function.
Thus all about:* URLs inherited security origin. This patch restricts
security origin inheritance to empty, about:blank, and about:srcdoc URLs.
Quotes and links from the WHATWG spec regarding about:srcdoc:
7.1 Browsing contexts
A browsing context can have a creator browsing context, the browsing context
that was responsible for its creation. If a browsing context has a parent
browsing context, then that is its creator browsing context. Otherwise, if the
browsing context has an opener browsing context, then that is its creator
browsing context. Otherwise, the browsing context has no creator browsing
context.
https://html.spec.whatwg.org/multipage/browsers.html#concept-document-bc
7.1.1 Nested browsing contexts
Certain elements (for example, iframe elements) can instantiate further
browsing contexts. These are called nested browsing contexts. If a browsing
context P has a Document D with an element E that nests another browsing
context C inside it, then C is said to be nested through D, and E is said to
be the browsing context container of C. If the browsing context container
element E is in the Document D, then P is said to be the parent browsing
context of C and C is said to be a child browsing context of P. Otherwise,
the nested browsing context C has no parent browsing context.
https://html.spec.whatwg.org/multipage/browsers.html#nested-browsing-context
4.8.5 The iframe element
The iframe element represents a nested browsing context.
...
If the srcdoc attribute is specified
Navigate the element's child browsing context to a new response whose
url list consists of about:srcdoc ...
https://html.spec.whatwg.org/multipage/embedded-content.html#attr-iframe-srcdoc
* dom/Document.cpp:
(WebCore::Document::initSecurityContext):
Now uses the URL::shouldInheritSecurityOriginFromOwner() function instead.
(WebCore::Document::initContentSecurityPolicy):
Now uses the URL::shouldInheritSecurityOriginFromOwner() function instead.
(WebCore::shouldInheritSecurityOriginFromOwner): Deleted.
Moved to URL::shouldInheritSecurityOriginFromOwner() and restricted the check.
* platform/URL.cpp:
(WebCore::URL::shouldInheritSecurityOriginFromOwner):
* platform/URL.h:
Moved the function from Document and restricted the check to only allow
security origin inheritance for empty, about:blank, and about:srcdoc URLs.
LayoutTests:
* http/tests/dom/window-open-about-blank-and-access-document-expected.txt: Added.
* http/tests/dom/window-open-about-blank-and-access-document.html: Added.
* http/tests/dom/window-open-about-webkit-org-and-access-document-expected.txt: Added.
* http/tests/dom/window-open-about-webkit-org-and-access-document.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (202150 => 202151)
--- trunk/LayoutTests/ChangeLog 2016-06-17 00:45:42 UTC (rev 202150)
+++ trunk/LayoutTests/ChangeLog 2016-06-17 01:10:08 UTC (rev 202151)
@@ -1,3 +1,16 @@
+2016-06-16 John Wilander <[email protected]>
+
+ Restrict security origin inheritance to empty, about:blank, and about:srcdoc URLs
+ https://bugs.webkit.org/show_bug.cgi?id=158855
+ <rdar://problem/26142632>
+
+ Reviewed by Alex Christensen.
+
+ * http/tests/dom/window-open-about-blank-and-access-document-expected.txt: Added.
+ * http/tests/dom/window-open-about-blank-and-access-document.html: Added.
+ * http/tests/dom/window-open-about-webkit-org-and-access-document-expected.txt: Added.
+ * http/tests/dom/window-open-about-webkit-org-and-access-document.html: Added.
+
2016-06-16 Jiewen Tan <[email protected]>
Move most of CSP tests into security/contentSecurityPolicy/
Added: trunk/LayoutTests/http/tests/dom/window-open-about-blank-and-access-document-expected.txt (0 => 202151)
--- trunk/LayoutTests/http/tests/dom/window-open-about-blank-and-access-document-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/dom/window-open-about-blank-and-access-document-expected.txt 2016-06-17 01:10:08 UTC (rev 202151)
@@ -0,0 +1,4 @@
+CONSOLE MESSAGE: line 1: Injected script running.
+
+PASS newWindow.document is defined.
+
Added: trunk/LayoutTests/http/tests/dom/window-open-about-blank-and-access-document.html (0 => 202151)
--- trunk/LayoutTests/http/tests/dom/window-open-about-blank-and-access-document.html (rev 0)
+++ trunk/LayoutTests/http/tests/dom/window-open-about-blank-and-access-document.html 2016-06-17 01:10:08 UTC (rev 202151)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Tests opening a new about:blank window and accessing its document</title>
+ <script src=""
+ <script>
+ var newWindow;
+
+ if (window.testRunner) {
+ testRunner.setCanOpenWindows();
+ testRunner.waitUntilDone();
+ }
+
+ function checkNewWindowDocumentIsUndefined () {
+ shouldBeDefined("newWindow.document");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+
+ function clickHandler() {
+ newWindow = window.open("about:blank");
+ try {
+ newWindow.document.write("<scri" + "pt>console.log('Injected script running.')</sc" + "ript>");
+ setTimeout(checkNewWindowDocumentIsUndefined, 500);
+ } catch (e) {
+ testFailed("Was not able to write to the new window's document.");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+ }
+
+ function clickButton() {
+ var button = document.getElementById("test");
+ var buttonX = button.offsetLeft + button.offsetWidth / 2;
+ var buttonY = button.offsetTop + button.offsetHeight / 2;
+ if (window.eventSender) {
+ eventSender.mouseMoveTo(buttonX, buttonY);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+ }
+ }
+ </script>
+</head>
+<body _onload_="clickButton()">
+<button id="test" _onclick_="clickHandler()"></button>
+<div id="console"></div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/http/tests/dom/window-open-about-webkit-org-and-access-document-expected.txt (0 => 202151)
--- trunk/LayoutTests/http/tests/dom/window-open-about-webkit-org-and-access-document-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/dom/window-open-about-webkit-org-and-access-document-expected.txt 2016-06-17 01:10:08 UTC (rev 202151)
@@ -0,0 +1,7 @@
+CONSOLE MESSAGE: line 45: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "null". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "about". Protocols must match.
+
+CONSOLE MESSAGE: line 347: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "null". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "about". Protocols must match.
+
+
+PASS newWindow.document is undefined.
+
Added: trunk/LayoutTests/http/tests/dom/window-open-about-webkit-org-and-access-document.html (0 => 202151)
--- trunk/LayoutTests/http/tests/dom/window-open-about-webkit-org-and-access-document.html (rev 0)
+++ trunk/LayoutTests/http/tests/dom/window-open-about-webkit-org-and-access-document.html 2016-06-17 01:10:08 UTC (rev 202151)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Tests opening a new about://webkit.org window and accessing its document</title>
+ <script src=""
+ <script>
+ var newWindow;
+
+ if (window.testRunner) {
+ testRunner.setCanOpenWindows();
+ testRunner.waitUntilDone();
+ }
+
+ function checkNewWindowDocumentIsUndefined () {
+ shouldBeUndefined("newWindow.document");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+
+ function clickHandler() {
+ newWindow = window.open("about://webkit.org");
+ try {
+ newWindow.document.write("<scri" + "pt>console.log('Injected script running.')</sc" + "ript>");
+ testFailed("Was able to write to the new window's document.");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ } catch (e) {
+ setTimeout(checkNewWindowDocumentIsUndefined, 500);
+ }
+ }
+
+ function clickButton() {
+ var button = document.getElementById("test");
+ var buttonX = button.offsetLeft + button.offsetWidth / 2;
+ var buttonY = button.offsetTop + button.offsetHeight / 2;
+ if (window.eventSender) {
+ eventSender.mouseMoveTo(buttonX, buttonY);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+ }
+ }
+ </script>
+</head>
+<body _onload_="clickButton()">
+<button id="test" _onclick_="clickHandler()"></button>
+<div id="console"></div>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (202150 => 202151)
--- trunk/Source/WebCore/ChangeLog 2016-06-17 00:45:42 UTC (rev 202150)
+++ trunk/Source/WebCore/ChangeLog 2016-06-17 01:10:08 UTC (rev 202151)
@@ -1,3 +1,63 @@
+2016-06-16 John Wilander <[email protected]>
+
+ Restrict security origin inheritance to empty, about:blank, and about:srcdoc URLs
+ https://bugs.webkit.org/show_bug.cgi?id=158855
+ <rdar://problem/26142632>
+
+ Reviewed by Alex Christensen.
+
+ Tests: http/tests/dom/window-open-about-blank-and-access-document.html
+ http/tests/dom/window-open-about-webkit-org-and-access-document.html
+
+ Document.cpp previously checked whether a document should inherit its owner's
+ security origin by checking if the URL is either empty or blank. URL.cpp in
+ turn only checks if the protocol is "about:" in the isBlankURL() function.
+ Thus all about:* URLs inherited security origin. This patch restricts
+ security origin inheritance to empty, about:blank, and about:srcdoc URLs.
+
+ Quotes and links from the WHATWG spec regarding about:srcdoc:
+
+ 7.1 Browsing contexts
+ A browsing context can have a creator browsing context, the browsing context
+ that was responsible for its creation. If a browsing context has a parent
+ browsing context, then that is its creator browsing context. Otherwise, if the
+ browsing context has an opener browsing context, then that is its creator
+ browsing context. Otherwise, the browsing context has no creator browsing
+ context.
+ https://html.spec.whatwg.org/multipage/browsers.html#concept-document-bc
+
+ 7.1.1 Nested browsing contexts
+ Certain elements (for example, iframe elements) can instantiate further
+ browsing contexts. These are called nested browsing contexts. If a browsing
+ context P has a Document D with an element E that nests another browsing
+ context C inside it, then C is said to be nested through D, and E is said to
+ be the browsing context container of C. If the browsing context container
+ element E is in the Document D, then P is said to be the parent browsing
+ context of C and C is said to be a child browsing context of P. Otherwise,
+ the nested browsing context C has no parent browsing context.
+ https://html.spec.whatwg.org/multipage/browsers.html#nested-browsing-context
+
+ 4.8.5 The iframe element
+ The iframe element represents a nested browsing context.
+ ...
+ If the srcdoc attribute is specified
+ Navigate the element's child browsing context to a new response whose
+ url list consists of about:srcdoc ...
+ https://html.spec.whatwg.org/multipage/embedded-content.html#attr-iframe-srcdoc
+
+ * dom/Document.cpp:
+ (WebCore::Document::initSecurityContext):
+ Now uses the URL::shouldInheritSecurityOriginFromOwner() function instead.
+ (WebCore::Document::initContentSecurityPolicy):
+ Now uses the URL::shouldInheritSecurityOriginFromOwner() function instead.
+ (WebCore::shouldInheritSecurityOriginFromOwner): Deleted.
+ Moved to URL::shouldInheritSecurityOriginFromOwner() and restricted the check.
+ * platform/URL.cpp:
+ (WebCore::URL::shouldInheritSecurityOriginFromOwner):
+ * platform/URL.h:
+ Moved the function from Document and restricted the check to only allow
+ security origin inheritance for empty, about:blank, and about:srcdoc URLs.
+
2016-06-16 Simon Fraser <[email protected]>
[iOS] Focus event dispatched in iframe causes parent document to scroll incorrectly
Modified: trunk/Source/WebCore/dom/Document.cpp (202150 => 202151)
--- trunk/Source/WebCore/dom/Document.cpp 2016-06-17 00:45:42 UTC (rev 202150)
+++ trunk/Source/WebCore/dom/Document.cpp 2016-06-17 01:10:08 UTC (rev 202151)
@@ -349,19 +349,6 @@
return true;
}
-static bool shouldInheritSecurityOriginFromOwner(const URL& url)
-{
- // http://www.whatwg.org/specs/web-apps/current-work/#origin-0
- //
- // If a Document has the address "about:blank"
- // The origin of the Document is the origin it was assigned when its browsing context was created.
- //
- // Note: We generalize this to all "blank" URLs and invalid URLs because we
- // treat all of these URLs as about:blank.
- //
- return url.isEmpty() || url.isBlankURL();
-}
-
static Widget* widgetForElement(Element* focusedElement)
{
if (!focusedElement)
@@ -5273,7 +5260,7 @@
setBaseURLOverride(parentDocument->baseURL());
}
- if (!shouldInheritSecurityOriginFromOwner(m_url))
+ if (!m_url.shouldInheritSecurityOriginFromOwner())
return;
// If we do not obtain a meaningful origin from the URL, then we try to
@@ -5316,7 +5303,7 @@
void Document::initContentSecurityPolicy()
{
- if (!m_frame->tree().parent() || (!shouldInheritSecurityOriginFromOwner(m_url) && !isPluginDocument()))
+ if (!m_frame->tree().parent() || (!m_url.shouldInheritSecurityOriginFromOwner() && !isPluginDocument()))
return;
contentSecurityPolicy()->copyStateFrom(m_frame->tree().parent()->document()->contentSecurityPolicy());
Modified: trunk/Source/WebCore/platform/URL.cpp (202150 => 202151)
--- trunk/Source/WebCore/platform/URL.cpp 2016-06-17 00:45:42 UTC (rev 202150)
+++ trunk/Source/WebCore/platform/URL.cpp 2016-06-17 01:10:08 UTC (rev 202151)
@@ -2062,6 +2062,13 @@
return protocolIs("about");
}
+bool URL::shouldInheritSecurityOriginFromOwner() const
+{
+ return isEmpty()
+ || m_string == blankURL().string()
+ || m_string == "about:srcdoc";
+}
+
typedef HashMap<String, unsigned short, ASCIICaseInsensitiveHash> DefaultPortsMap;
static const DefaultPortsMap& defaultPortsMap()
{
Modified: trunk/Source/WebCore/platform/URL.h (202150 => 202151)
--- trunk/Source/WebCore/platform/URL.h 2016-06-17 00:45:42 UTC (rev 202150)
+++ trunk/Source/WebCore/platform/URL.h 2016-06-17 01:10:08 UTC (rev 202151)
@@ -131,6 +131,7 @@
bool protocolIsInHTTPFamily() const;
WEBCORE_EXPORT bool isLocalFile() const;
bool isBlankURL() const;
+ bool shouldInheritSecurityOriginFromOwner() const;
WEBCORE_EXPORT bool setProtocol(const String&);
void setHost(const String&);