Move Document::domainIsRegisterable to SecurityOrigin::isMatchingRegistrableDomainSuffix
authorjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 May 2019 22:08:00 +0000 (22:08 +0000)
committerjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 May 2019 22:08:00 +0000 (22:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181950
<rdar://problem/43357371>

Reviewed by Brent Fulgham.

Source/WebCore:

This patch moves Document::domainIsRegisterable to SecurityOrigin::isMatchingRegistrableDomainSuffix
to be more aligned with the HTML standard:
https://html.spec.whatwg.org/multipage/origin.html#is-a-registrable-domain-suffix-of-or-is-equal-to.
Besides that, it also removes redundant codes within the original method that is also done in
OriginAccessEntry::matchesOrigin.

Covered by new API tests.

* dom/Document.cpp:
(WebCore::Document::setDomain):
(WebCore::Document::domainIsRegisterable const): Deleted.
* dom/Document.h:
* page/SecurityOrigin.cpp:
(WebCore::SecurityOrigin::isMatchingRegistrableDomainSuffix const):
* page/SecurityOrigin.h:

Tools:

* TestWebKitAPI/Tests/WebCore/SecurityOrigin.cpp:
(TestWebKitAPI::TEST_F):

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

Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/page/SecurityOrigin.cpp
Source/WebCore/page/SecurityOrigin.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/SecurityOrigin.cpp

index 0e4a7fd..08fd31b 100644 (file)
@@ -1,3 +1,27 @@
+2019-05-01  Jiewen Tan  <jiewen_tan@apple.com>
+
+        Move Document::domainIsRegisterable to SecurityOrigin::isMatchingRegistrableDomainSuffix
+        https://bugs.webkit.org/show_bug.cgi?id=181950
+        <rdar://problem/43357371>
+
+        Reviewed by Brent Fulgham.
+
+        This patch moves Document::domainIsRegisterable to SecurityOrigin::isMatchingRegistrableDomainSuffix
+        to be more aligned with the HTML standard:
+        https://html.spec.whatwg.org/multipage/origin.html#is-a-registrable-domain-suffix-of-or-is-equal-to.
+        Besides that, it also removes redundant codes within the original method that is also done in
+        OriginAccessEntry::matchesOrigin.
+
+        Covered by new API tests.
+
+        * dom/Document.cpp:
+        (WebCore::Document::setDomain):
+        (WebCore::Document::domainIsRegisterable const): Deleted.
+        * dom/Document.h:
+        * page/SecurityOrigin.cpp:
+        (WebCore::SecurityOrigin::isMatchingRegistrableDomainSuffix const):
+        * page/SecurityOrigin.h:
+
 2019-05-01  Ryosuke Niwa  <rniwa@webkit.org>
 
         [iOS] Element::focus and Element::scrollIntoView do not clamp scroll positions
index 24b7018..c983dc0 100644 (file)
 #include "NodeIterator.h"
 #include "NodeRareData.h"
 #include "NodeWithIndex.h"
-#include "OriginAccessEntry.h"
 #include "OverflowEvent.h"
 #include "PageConsoleClient.h"
 #include "PageGroup.h"
@@ -4857,49 +4856,6 @@ String Document::domain() const
     return securityOrigin().domain();
 }
 
-bool Document::domainIsRegisterable(const String& newDomain) const
-{
-    if (newDomain.isEmpty())
-        return false;
-
-    const String& effectiveDomain = domain();
-
-    // If the new domain is the same as the old domain, return true so that
-    // we still call securityOrigin().setDomainForDOM. This will change the
-    // security check behavior. For example, if a page loaded on port 8000
-    // assigns its current domain using document.domain, the page will
-    // allow other pages loaded on different ports in the same domain that
-    // have also assigned to access this page.
-    if (equalIgnoringASCIICase(effectiveDomain, newDomain))
-        return true;
-
-    // e.g. newDomain = webkit.org (10) and domain() = www.webkit.org (14)
-    unsigned oldLength = effectiveDomain.length();
-    unsigned newLength = newDomain.length();
-    if (newLength >= oldLength)
-        return false;
-
-    auto ipAddressSetting = settings().treatIPAddressAsDomain() ? OriginAccessEntry::TreatIPAddressAsDomain : OriginAccessEntry::TreatIPAddressAsIPAddress;
-    OriginAccessEntry accessEntry { securityOrigin().protocol(), newDomain, OriginAccessEntry::AllowSubdomains, ipAddressSetting };
-    if (!accessEntry.matchesOrigin(securityOrigin()))
-        return false;
-
-    if (effectiveDomain[oldLength - newLength - 1] != '.')
-        return false;
-    if (StringView { effectiveDomain }.substring(oldLength - newLength) != newDomain)
-        return false;
-
-    auto potentialPublicSuffix = newDomain;
-    if (potentialPublicSuffix.startsWith('.'))
-        potentialPublicSuffix.remove(0, 1);
-
-#if ENABLE(PUBLIC_SUFFIX_LIST)
-    return !isPublicSuffix(potentialPublicSuffix);
-#else
-    return true;
-#endif
-}
-
 ExceptionOr<void> Document::setDomain(const String& newDomain)
 {
     if (!frame())
@@ -4917,7 +4873,7 @@ ExceptionOr<void> Document::setDomain(const String& newDomain)
     if (effectiveDomain.isEmpty())
         return Exception { SecurityError, "The document has a null effectiveDomain." };
 
-    if (!domainIsRegisterable(newDomain))
+    if (!securityOrigin().isMatchingRegistrableDomainSuffix(newDomain, settings().treatIPAddressAsDomain()))
         return Exception { SecurityError, "Attempted to use a non-registrable domain." };
 
     securityOrigin().setDomainFromDOM(newDomain);
index 45f8598..941d5f5 100644 (file)
@@ -1644,8 +1644,6 @@ private:
 
     void platformSuspendOrStopActiveDOMObjects();
 
-    bool domainIsRegisterable(const String&) const;
-
     void enableTemporaryTimeUserGesture();
 
     bool isBodyPotentiallyScrollable(HTMLBodyElement&);
index ddcc7d2..7b7cf2c 100644 (file)
@@ -30,6 +30,7 @@
 #include "SecurityOrigin.h"
 
 #include "BlobURL.h"
+#include "OriginAccessEntry.h"
 #include "SchemeRegistry.h"
 #include "SecurityPolicy.h"
 #include "TextEncoding.h"
@@ -432,6 +433,27 @@ bool SecurityOrigin::isSameOriginAs(const SecurityOrigin& other) const
     return isSameSchemeHostPort(other);
 }
 
+bool SecurityOrigin::isMatchingRegistrableDomainSuffix(const String& domainSuffix, bool treatIPAddressAsDomain) const
+{
+    if (domainSuffix.isEmpty())
+        return false;
+
+    auto ipAddressSetting = treatIPAddressAsDomain ? OriginAccessEntry::TreatIPAddressAsDomain : OriginAccessEntry::TreatIPAddressAsIPAddress;
+    OriginAccessEntry accessEntry { protocol(), domainSuffix, OriginAccessEntry::AllowSubdomains, ipAddressSetting };
+    if (!accessEntry.matchesOrigin(*this))
+        return false;
+
+    // Always return true if it is an exact match.
+    if (domainSuffix.length() == host().length())
+        return true;
+
+#if ENABLE(PUBLIC_SUFFIX_LIST)
+    return !isPublicSuffix(domainSuffix);
+#else
+    return true;
+#endif
+}
+
 void SecurityOrigin::grantLoadLocalResources()
 {
     // Granting privileges to some, but not all, documents in a SecurityOrigin
index 9a95b45..31b6b3d 100644 (file)
@@ -204,6 +204,10 @@ public:
     // https://html.spec.whatwg.org/multipage/browsers.html#same-origin
     WEBCORE_EXPORT bool isSameOriginAs(const SecurityOrigin&) const;
 
+    // This method implements the "is a registrable domain suffix of or is equal to" algorithm from the HTML Standard:
+    // https://html.spec.whatwg.org/multipage/origin.html#is-a-registrable-domain-suffix-of-or-is-equal-to
+    WEBCORE_EXPORT bool isMatchingRegistrableDomainSuffix(const String&, bool treatIPAddressAsDomain = false) const;
+
     bool isPotentiallyTrustworthy() const { return m_isPotentiallyTrustworthy; }
     void setIsPotentiallyTrustworthy(bool value) { m_isPotentiallyTrustworthy = value; }
 
index bbad75a..c2c187a 100644 (file)
@@ -1,3 +1,14 @@
+2019-05-01  Jiewen Tan  <jiewen_tan@apple.com>
+
+        Move Document::domainIsRegisterable to SecurityOrigin::isMatchingRegistrableDomainSuffix
+        https://bugs.webkit.org/show_bug.cgi?id=181950
+        <rdar://problem/43357371>
+
+        Reviewed by Brent Fulgham.
+
+        * TestWebKitAPI/Tests/WebCore/SecurityOrigin.cpp:
+        (TestWebKitAPI::TEST_F):
+
 2019-05-01  Aakash Jain  <aakash_jain@apple.com>
 
         Remove webkitpy and bindings EWS queues from dashboard
index a41ab4b..bf88878 100644 (file)
@@ -183,4 +183,44 @@ TEST_F(SecurityOriginTest, IsPotentiallyTrustworthy)
     EXPECT_FALSE(SecurityOrigin::createFromString("dummy:a")->isPotentiallyTrustworthy());
 }
 
+TEST_F(SecurityOriginTest, IsRegistrableDomainSuffix)
+{
+    auto exampleOrigin = SecurityOrigin::create(URL(URL(), "http://www.example.com"));
+    EXPECT_TRUE(exampleOrigin->isMatchingRegistrableDomainSuffix("example.com"));
+    EXPECT_TRUE(exampleOrigin->isMatchingRegistrableDomainSuffix("www.example.com"));
+#if !ENABLE(PUBLIC_SUFFIX_LIST)
+    EXPECT_TRUE(exampleOrigin->isMatchingRegistrableDomainSuffix("com"));
+#endif
+    EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix(""));
+    EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix("."));
+    EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix(".example.com"));
+    EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix(".www.example.com"));
+    EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix("example.com."));
+#if ENABLE(PUBLIC_SUFFIX_LIST)
+    EXPECT_FALSE(exampleOrigin->isMatchingRegistrableDomainSuffix("com"));
+#endif
+
+    auto exampleDotOrigin = SecurityOrigin::create(URL(URL(), "http://www.example.com."));
+    EXPECT_TRUE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("example.com."));
+    EXPECT_TRUE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("www.example.com."));
+#if !ENABLE(PUBLIC_SUFFIX_LIST)
+    EXPECT_TRUE(exampleOrigin->isMatchingRegistrableDomainSuffix("com."));
+#endif
+    EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix(""));
+    EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("."));
+    EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix(".example.com."));
+    EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix(".www.example.com."));
+    EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("example.com"));
+#if ENABLE(PUBLIC_SUFFIX_LIST)
+    EXPECT_FALSE(exampleDotOrigin->isMatchingRegistrableDomainSuffix("com"));
+#endif
+
+    auto ipOrigin = SecurityOrigin::create(URL(URL(), "http://127.0.0.1"));
+    EXPECT_TRUE(ipOrigin->isMatchingRegistrableDomainSuffix("127.0.0.1", true));
+    EXPECT_FALSE(ipOrigin->isMatchingRegistrableDomainSuffix("127.0.0.2", true));
+
+    auto comOrigin = SecurityOrigin::create(URL(URL(), "http://com"));
+    EXPECT_TRUE(comOrigin->isMatchingRegistrableDomainSuffix("com"));
+}
+
 } // namespace TestWebKitAPI