Ignore URL host for schemes that are not using host information
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 30 Dec 2019 17:10:13 +0000 (17:10 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 30 Dec 2019 17:10:13 +0000 (17:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=205157
Source/WebCore:

rdar://problem/57825963

Reviewed by Darin Adler.

Tests: http/tests/local/file-url-host.html
       http/tests/security/about-url-host.html
       http/tests/security/data-url-host.html
       http/tests/security/javascript-url-host.html

Whenever setting the document URL, remove the host information if its scheme is not supposed to have a host.
This is done for file, data and about schemes.

Add internals APIs to test this.

* dom/Document.cpp:
(WebCore::Document::setURL):
* page/DOMWindow.h:
* page/Location.h:
* page/Location.idl:
* page/SecurityOrigin.cpp:
(WebCore::SecurityOrigin::shouldIgnoreHost):
* page/SecurityOrigin.h:
* testing/Internals.cpp:
(WebCore::Internals::windowLocationHost):
* testing/Internals.h:
* testing/Internals.idl:

Source/WTF:

<rdar://problem/57825963>

Reviewed by Darin Adler.

* wtf/URL.cpp:
(WTF::URL::removeHostAndPort):
* wtf/URL.h:

LayoutTests:

Reviewed by Darin Adler.

* http/tests/local/file-url-host-expected.txt: Added.
* http/tests/local/file-url-host.html: Added.
* http/tests/security/about-url-host-expected.txt: Added.
* http/tests/security/about-url-host.html: Added.
* http/tests/security/data-url-host-expected.txt: Added.
* http/tests/security/data-url-host.html: Added.
* http/tests/security/javascript-url-host-expected.txt: Added.
* http/tests/security/javascript-url-host.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@253946 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/local/file-url-host-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/local/file-url-host.html [new file with mode: 0644]
LayoutTests/http/tests/security/about-url-host-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/about-url-host.html [new file with mode: 0644]
LayoutTests/http/tests/security/data-url-host-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/data-url-host.html [new file with mode: 0644]
LayoutTests/http/tests/security/javascript-url-host-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/javascript-url-host.html [new file with mode: 0644]
Source/WTF/ChangeLog
Source/WTF/wtf/URL.cpp
Source/WTF/wtf/URL.h
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/page/DOMWindow.h
Source/WebCore/page/Location.h
Source/WebCore/page/Location.idl
Source/WebCore/page/SecurityOrigin.cpp
Source/WebCore/page/SecurityOrigin.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index d773027..35ffc5e 100644 (file)
@@ -1,3 +1,19 @@
+2019-12-30  youenn fablet  <youenn@apple.com>
+
+        Ignore URL host for schemes that are not using host information
+        https://bugs.webkit.org/show_bug.cgi?id=205157
+
+        Reviewed by Darin Adler.
+
+        * http/tests/local/file-url-host-expected.txt: Added.
+        * http/tests/local/file-url-host.html: Added.
+        * http/tests/security/about-url-host-expected.txt: Added.
+        * http/tests/security/about-url-host.html: Added.
+        * http/tests/security/data-url-host-expected.txt: Added.
+        * http/tests/security/data-url-host.html: Added.
+        * http/tests/security/javascript-url-host-expected.txt: Added.
+        * http/tests/security/javascript-url-host.html: Added.
+
 2019-12-27  Dean Jackson  <dino@apple.com>
 
         [WebGL] Add a pure virtual base class for GraphicsContext3D
diff --git a/LayoutTests/http/tests/local/file-url-host-expected.txt b/LayoutTests/http/tests/local/file-url-host-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/http/tests/local/file-url-host.html b/LayoutTests/http/tests/local/file-url-host.html
new file mode 100644 (file)
index 0000000..101c9f8
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<body>
+<script>
+    if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.dumpAsText();
+    }
+    if (location.hash === "")
+        window.location = window.location.href.replace("file:///", "file://example.org/") + "?test#test-host";
+    else if (location.hash === "#test")
+        window.location = window.location.href.replace("file://example.org/", "file:///").replace("?test#test-host", "") + "?test2#test-host" + window.location.host;
+    else {
+        document.body.innerHTML = window.location.hash === "#test-host" ? "PASS": ("FAIL, got: " + window.location.hash);
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }
+</script>
+</body>
diff --git a/LayoutTests/http/tests/security/about-url-host-expected.txt b/LayoutTests/http/tests/security/about-url-host-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/http/tests/security/about-url-host.html b/LayoutTests/http/tests/security/about-url-host.html
new file mode 100644 (file)
index 0000000..8c329be
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<body>
+<script>
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+function test() {
+    try {
+        if (window.internals) {
+            const host = internals.windowLocationHost(testFrame.contentWindow);
+            document.body.innerHTML = host === "" ? "PASS" : "FAIL, got " + host;
+        }
+    } catch (e) {
+        console.log(e);
+    }
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+</script>
+<iframe id="testFrame" onload="test()" src="about://example.org"></iframe>
+</body>
diff --git a/LayoutTests/http/tests/security/data-url-host-expected.txt b/LayoutTests/http/tests/security/data-url-host-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/http/tests/security/data-url-host.html b/LayoutTests/http/tests/security/data-url-host.html
new file mode 100644 (file)
index 0000000..8616244
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<body>
+<script>
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+function test() {
+    try {
+        if (window.internals) {
+            const host = internals.windowLocationHost(testFrame.contentWindow);
+            document.body.innerHTML = host === "" ? "PASS" : "FAIL, got " + host;
+        }
+    } catch (e) {
+        console.log(e);
+    }
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+</script>
+<iframe id="testFrame" onload="test()" src="data://example.org/text/html,test"></iframe>
+</body>
diff --git a/LayoutTests/http/tests/security/javascript-url-host-expected.txt b/LayoutTests/http/tests/security/javascript-url-host-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/http/tests/security/javascript-url-host.html b/LayoutTests/http/tests/security/javascript-url-host.html
new file mode 100644 (file)
index 0000000..a94aa6a
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<body>
+<script>
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+function test() {
+    try {
+        if (window.internals) {
+            const host = internals.windowLocationHost(testFrame.contentWindow);
+            document.body.innerHTML = host === "" ? "PASS" : "FAIL, got " + host;
+        }
+    } catch (e) {
+        console.log(e);
+    }
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+</script>
+<iframe id="testFrame" onload="test()" src="javascript://example.org/alert('test')"></iframe>
+</body>
index 7df4872..b7202b5 100644 (file)
@@ -1,3 +1,15 @@
+2019-12-30  youenn fablet  <youenn@apple.com>
+
+        Ignore URL host for schemes that are not using host information
+        https://bugs.webkit.org/show_bug.cgi?id=205157
+        <rdar://problem/57825963>
+
+        Reviewed by Darin Adler.
+
+        * wtf/URL.cpp:
+        (WTF::URL::removeHostAndPort):
+        * wtf/URL.h:
+
 2019-12-25  Dean Jackson  <dino@apple.com>
 
         [WebGL] Enable ANGLE by default for Cocoa platforms (except simulator)
index 5f4f3f1..f9e3cbf 100644 (file)
@@ -474,6 +474,15 @@ void URL::setPort(unsigned short i)
     *this = parser.result();
 }
 
+void URL::removeHostAndPort()
+{
+    if (!m_isValid)
+        return;
+    if (!host().isEmpty())
+        setHost({ });
+    removePort();
+}
+
 void URL::setHostAndPort(const String& hostAndPort)
 {
     if (!m_isValid)
index 849741c..1cee528 100644 (file)
@@ -145,6 +145,7 @@ public:
 
     // Input is like "foo.com" or "foo.com:8000".
     void setHostAndPort(const String&);
+    void removeHostAndPort();
 
     void setUser(const String&);
     void setPass(const String&);
index 6c368b5..322e24f 100644 (file)
@@ -1,3 +1,34 @@
+2019-12-30  youenn fablet  <youenn@apple.com>
+
+        Ignore URL host for schemes that are not using host information
+        https://bugs.webkit.org/show_bug.cgi?id=205157
+        rdar://problem/57825963
+
+        Reviewed by Darin Adler.
+
+        Tests: http/tests/local/file-url-host.html
+               http/tests/security/about-url-host.html
+               http/tests/security/data-url-host.html
+               http/tests/security/javascript-url-host.html
+
+        Whenever setting the document URL, remove the host information if its scheme is not supposed to have a host.
+        This is done for file, data and about schemes.
+
+        Add internals APIs to test this.
+
+        * dom/Document.cpp:
+        (WebCore::Document::setURL):
+        * page/DOMWindow.h:
+        * page/Location.h:
+        * page/Location.idl:
+        * page/SecurityOrigin.cpp:
+        (WebCore::SecurityOrigin::shouldIgnoreHost):
+        * page/SecurityOrigin.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::windowLocationHost):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2019-12-29  Yusuke Suzuki  <ysuzuki@apple.com>
 
         Unreviewed, build fix after r253938
index 062f4ad..5e6fd74 100644 (file)
@@ -3235,6 +3235,9 @@ void Document::setURL(const URL& url)
         return;
 
     m_url = newURL;
+    if (SecurityOrigin::shouldIgnoreHost(m_url))
+        m_url.removeHostAndPort();
+
     m_documentURI = m_url.string();
     updateBaseURL();
 }
index 6003378..8f0d9c9 100644 (file)
@@ -176,7 +176,7 @@ public:
     Navigator* optionalNavigator() const { return m_navigator.get(); }
     Navigator& clientInformation() { return navigator(); }
 
-    Location& location();
+    WEBCORE_EXPORT Location& location();
     void setLocation(DOMWindow& activeWindow, const URL& completedURL, SetLocationLocking = LockHistoryBasedOnGestureState);
 
     DOMSelection* getSelection();
index 5fba18c..ba104dc 100644 (file)
@@ -52,7 +52,7 @@ public:
     ExceptionOr<void> setProtocol(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
     String protocol() const;
     ExceptionOr<void> setHost(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
-    String host() const;
+    WEBCORE_EXPORT String host() const;
     ExceptionOr<void> setHostname(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
     String hostname() const;
     ExceptionOr<void> setPort(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
index 85cb9ab..b0dcccd 100644 (file)
@@ -38,6 +38,7 @@
     CustomPut,
     CustomPutOnPrototype,
     CustomToStringName,
+    ExportMacro=WEBCORE_EXPORT,
     GenerateIsReachable=ReachableFromDOMWindow,
     IsImmutablePrototypeExoticObject,
     ImplementationLacksVTable,
index e900c21..b129a82 100644 (file)
@@ -56,6 +56,11 @@ static bool schemeRequiresHost(const URL& url)
     return url.protocolIsInHTTPFamily() || url.protocolIs("ftp");
 }
 
+bool SecurityOrigin::shouldIgnoreHost(const URL& url)
+{
+    return url.protocolIsData() || url.protocolIsAbout() || protocolIsJavaScript(url) || url.protocolIs("file");
+}
+
 bool SecurityOrigin::shouldUseInnerURL(const URL& url)
 {
     // FIXME: Blob URLs don't have inner URLs. Their form is "blob:<inner-origin>/<UUID>", so treating the part after "blob:" as a URL is incorrect.
index 6538f91..4090763 100644 (file)
@@ -88,6 +88,8 @@ public:
     const String& domain() const { return m_domain; }
     Optional<uint16_t> port() const { return m_data.port; }
 
+    static bool shouldIgnoreHost(const URL&);
+
     // Returns true if a given URL is secure, based either directly on its
     // own protocol, or, when relevant, on the protocol of its "inner URL"
     // Protocols like blob: and filesystem: fall into this latter category.
index 47018bd..00fad12 100644 (file)
 #include "LegacySchemeRegistry.h"
 #include "LibWebRTCProvider.h"
 #include "LoaderStrategy.h"
+#include "Location.h"
 #include "MallocStatistics.h"
 #include "MediaDevices.h"
 #include "MediaEngineConfigurationFactory.h"
@@ -5392,4 +5393,9 @@ bool Internals::hasSandboxMachLookupAccessToXPCServiceName(const String& process
 #endif
 }
 
+String Internals::windowLocationHost(DOMWindow& window)
+{
+    return window.location().host();
+}
+
 } // namespace WebCore
index fe4a856..e2a120f 100644 (file)
@@ -78,6 +78,7 @@ class InspectorStubFrontend;
 class InternalsMapLike;
 class InternalSettings;
 class InternalsSetLike;
+class Location;
 class MallocStatistics;
 class MediaSession;
 class MediaStream;
@@ -919,6 +920,8 @@ public:
 
     String highlightPseudoElementColor(const String& highlightName, Element&);
 
+    String windowLocationHost(DOMWindow&);
+
 private:
     explicit Internals(Document&);
     Document* contextDocument() const;
index f759cc9..cfbfe46 100644 (file)
@@ -770,6 +770,8 @@ enum CompositingPolicy {
     [CallWith=Document] void queueTaskToQueueMicrotask(DOMString source, VoidCallback callback);
     [MayThrowException] boolean hasSameEventLoopAs(WindowProxy windowProxy);
 
+    DOMString windowLocationHost(DOMWindow window);
+
     void markContextAsInsecure();
 
     void setMaxCanvasPixelMemory(unsigned long size);