Title: [127150] trunk/Source/WebCore
Revision
127150
Author
[email protected]
Date
2012-08-30 09:12:13 -0700 (Thu, 30 Aug 2012)

Log Message

[BlackBerry] Modifying how IP domains are handled in Cookies
https://bugs.webkit.org/show_bug.cgi?id=95381

Patch by Otto Derek Cheung <[email protected]> on 2012-08-30
Reviewed by Rob Buis.
Internally reviewed by Joe Mason.

Current implementation handles IP addresses like normal domains.
This makes invalid cross domain cookies possibe by setting cookie
domains to a suffix of the targeted IP. (ex. hackers on 11.121.61.97
can set cookies to 61.97, so they show up on the targeted website of
10.120.61.97)

New Implementation is to detect IP addresses and treat them without
exploding them with the delimiter ".". That way, IP addresses will
be stored as a whole and other IPs won't have access to it.

PR 130051

Manually tested by accessing a webpage via IP (hosted through
LAMP - ex:10.121.61.97) and tried to set cookies with domains that
are a suffix to the ip address (ex: .97, 121.61.97).
Also tried to set cookies to other ip addresses that "domain matches"
the IP address (ex. 11.121.61.97). Verified that they all failed.

Tested using the cookies test page: http://browser.swlab.rim.net/test/cookies

* platform/blackberry/CookieManager.cpp:
(WebCore::CookieManager::getRawCookies):
(WebCore::CookieManager::checkAndTreatCookie):
(WebCore::CookieManager::findOrCreateCookieMap):
* platform/blackberry/CookieManager.h:
* platform/blackberry/CookieParser.cpp:
(WebCore::CookieParser::CookieParser):
(WebCore::CookieParser::parseOneCookie):
* platform/blackberry/CookieParser.h:
(CookieParser):
* platform/blackberry/ParsedCookie.cpp:
(WebCore::ParsedCookie::ParsedCookie):
* platform/blackberry/ParsedCookie.h:
(WebCore::ParsedCookie::setDomain):
(WebCore::ParsedCookie::domainIsIPAddress):
(ParsedCookie):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (127149 => 127150)


--- trunk/Source/WebCore/ChangeLog	2012-08-30 16:08:27 UTC (rev 127149)
+++ trunk/Source/WebCore/ChangeLog	2012-08-30 16:12:13 UTC (rev 127150)
@@ -1,3 +1,48 @@
+2012-08-30  Otto Derek Cheung  <[email protected]>
+
+        [BlackBerry] Modifying how IP domains are handled in Cookies
+        https://bugs.webkit.org/show_bug.cgi?id=95381
+
+        Reviewed by Rob Buis.
+        Internally reviewed by Joe Mason.
+
+        Current implementation handles IP addresses like normal domains.
+        This makes invalid cross domain cookies possibe by setting cookie
+        domains to a suffix of the targeted IP. (ex. hackers on 11.121.61.97
+        can set cookies to 61.97, so they show up on the targeted website of
+        10.120.61.97)
+
+        New Implementation is to detect IP addresses and treat them without
+        exploding them with the delimiter ".". That way, IP addresses will
+        be stored as a whole and other IPs won't have access to it.
+
+        PR 130051
+
+        Manually tested by accessing a webpage via IP (hosted through
+        LAMP - ex:10.121.61.97) and tried to set cookies with domains that
+        are a suffix to the ip address (ex: .97, 121.61.97).
+        Also tried to set cookies to other ip addresses that "domain matches"
+        the IP address (ex. 11.121.61.97). Verified that they all failed.
+
+        Tested using the cookies test page: http://browser.swlab.rim.net/test/cookies
+
+        * platform/blackberry/CookieManager.cpp:
+        (WebCore::CookieManager::getRawCookies):
+        (WebCore::CookieManager::checkAndTreatCookie):
+        (WebCore::CookieManager::findOrCreateCookieMap):
+        * platform/blackberry/CookieManager.h:
+        * platform/blackberry/CookieParser.cpp:
+        (WebCore::CookieParser::CookieParser):
+        (WebCore::CookieParser::parseOneCookie):
+        * platform/blackberry/CookieParser.h:
+        (CookieParser):
+        * platform/blackberry/ParsedCookie.cpp:
+        (WebCore::ParsedCookie::ParsedCookie):
+        * platform/blackberry/ParsedCookie.h:
+        (WebCore::ParsedCookie::setDomain):
+        (WebCore::ParsedCookie::domainIsIPAddress):
+        (ParsedCookie):
+
 2012-08-30  Ilya Tikhonovsky  <[email protected]>
 
         Web Inspector: [regression] ui: heap profiler: splitter between containment and retainment views has white background.

Modified: trunk/Source/WebCore/platform/blackberry/CookieManager.cpp (127149 => 127150)


--- trunk/Source/WebCore/platform/blackberry/CookieManager.cpp	2012-08-30 16:08:27 UTC (rev 127149)
+++ trunk/Source/WebCore/platform/blackberry/CookieManager.cpp	2012-08-30 16:12:13 UTC (rev 127150)
@@ -40,6 +40,7 @@
 #include <BlackBerryPlatformMessageClient.h>
 #include <BlackBerryPlatformNavigatorHandler.h>
 #include <BlackBerryPlatformSettings.h>
+#include <network/DomainTools.h>
 #include <stdlib.h>
 #include <wtf/CurrentTime.h>
 #include <wtf/text/CString.h>
@@ -219,8 +220,15 @@
     }
 
     Vector<String> delimitedHost;
-    requestURL.host().lower().split(".", true, delimitedHost);
 
+    // IP addresses are stored in a particular format (due to ipv6). Reduce the ip address so we can match
+    // it with the one in memory.
+    string canonicalIP = BlackBerry::Platform::getCanonicalIPFormat(requestURL.host().utf8().data());
+    if (!canonicalIP.empty())
+        delimitedHost.append(String(canonicalIP.c_str()));
+    else
+        requestURL.host().lower().split(".", true, delimitedHost);
+
     // Go through all the protocol trees that we need to search for
     // and get all cookies that are valid for this domain
     for (size_t k = 0; k < protocolsToSearch.size(); k++) {
@@ -341,7 +349,7 @@
     // If protocol support domain, we have to traverse the domain tree to find the right
     // cookieMap to handle with
     if (!ignoreDomain)
-        curMap = findOrCreateCookieMap(curMap, candidateCookie->domain(), candidateCookie->hasExpired());
+        curMap = findOrCreateCookieMap(curMap, *candidateCookie);
 
     // Now that we have the proper map for this cookie, we can modify it
     // If cookie does not exist and has expired, delete it
@@ -475,12 +483,17 @@
     }
 }
 
-CookieMap* CookieManager::findOrCreateCookieMap(CookieMap* protocolMap, const String& domain, bool findOnly)
+CookieMap* CookieManager::findOrCreateCookieMap(CookieMap* protocolMap, const ParsedCookie& candidateCookie)
 {
     // Explode the domain with the '.' delimiter
     Vector<String> delimitedHost;
-    domain.split(".", delimitedHost);
 
+    // If the domain is an IP address, don't split it.
+    if (candidateCookie.domainIsIPAddress())
+        delimitedHost.append(candidateCookie.domain());
+    else
+        candidateCookie.domain().split(".", delimitedHost);
+
     CookieMap* curMap = protocolMap;
     size_t hostSize = delimitedHost.size();
 
@@ -494,7 +507,7 @@
         CookieMap* nextMap = curMap->getSubdomainMap(delimitedHost[i]);
         if (!nextMap) {
             CookieLog("CookieManager - cannot find map\n");
-            if (findOnly)
+            if (candidateCookie.hasExpired())
                 return 0;
             CookieLog("CookieManager - creating %s in currentmap %s\n", delimitedHost[i].utf8().data(), curMap->getName().utf8().data());
             nextMap = new CookieMap(delimitedHost[i]);

Modified: trunk/Source/WebCore/platform/blackberry/CookieManager.h (127149 => 127150)


--- trunk/Source/WebCore/platform/blackberry/CookieManager.h	2012-08-30 16:08:27 UTC (rev 127149)
+++ trunk/Source/WebCore/platform/blackberry/CookieManager.h	2012-08-30 16:12:13 UTC (rev 127150)
@@ -114,7 +114,7 @@
 
     void addCookieToMap(CookieMap* targetMap, ParsedCookie* candidateCookie, BackingStoreRemovalPolicy postToBackingStore, CookieFilter = WithHttpOnlyCookies);
 
-    CookieMap* findOrCreateCookieMap(CookieMap* protocolMap, const String& domain, bool findOnly);
+    CookieMap* findOrCreateCookieMap(CookieMap* protocolMap, const ParsedCookie& candidateCookie);
 
     void initiateCookieLimitCleanUp();
     void cookieLimitCleanUp(Timer<CookieManager>*);

Modified: trunk/Source/WebCore/platform/blackberry/CookieParser.cpp (127149 => 127150)


--- trunk/Source/WebCore/platform/blackberry/CookieParser.cpp	2012-08-30 16:08:27 UTC (rev 127149)
+++ trunk/Source/WebCore/platform/blackberry/CookieParser.cpp	2012-08-30 16:12:13 UTC (rev 127150)
@@ -55,6 +55,14 @@
 CookieParser::CookieParser(const KURL& defaultCookieURL)
     : m_defaultCookieURL(defaultCookieURL)
 {
+    m_defaultCookieHost = defaultCookieURL.host();
+    m_defaultDomainIsIPAddress = false;
+    string hostDomainCanonical = BlackBerry::Platform::getCanonicalIPFormat(m_defaultCookieHost.utf8().data()).c_str();
+    if (!hostDomainCanonical.empty()) {
+        m_defaultCookieHost = String(hostDomainCanonical.c_str());
+        m_defaultDomainIsIPAddress = true;
+    } else
+        m_defaultCookieHost = m_defaultCookieHost.startsWith(".") ? m_defaultCookieHost : "." + m_defaultCookieHost;
 }
 
 CookieParser::~CookieParser()
@@ -260,24 +268,38 @@
                 // For example: ab.c.com dose not domain match b.c.com;
                 String realDomain = parsedValue[0] == '.' ? parsedValue : "." + parsedValue;
 
-                // The request host should domain match the Domain attribute.
-                // Domain string starts with a dot, so a.b.com should domain match .a.b.com.
-                // add a "." at beginning of host name, because it can handle many cases such as
-                // a.b.com matches b.com, a.b.com matches .B.com and a.b.com matches .A.b.Com
-                // and so on.
-                String hostDomainName = m_defaultCookieURL.host();
-                hostDomainName = hostDomainName.startsWith('.') ? hostDomainName : "." + hostDomainName;
-                if (!hostDomainName.endsWith(realDomain, false))
-                    LOG_AND_DELETE("Invalid cookie %s (domain): it does not domain match the host");
-                // We should check for an embedded dot in the portion of string in the host not in the domain
-                // but to match firefox behaviour we do not.
+                // Try to return an canonical ip address if the domain is an ip
 
-                // Check whether the domain is a top level domain, if it is throw it out
-                // http://publicsuffix.org/list/
-                if (BlackBerry::Platform::isTopLevelDomain(realDomain.utf8().data()))
-                    LOG_AND_DELETE("Invalid cookie %s (domain): it did not pass the top level domain check", cookie.ascii().data());
+                bool isIPAddress = false;
+                // We only check if the current domain is an IP address when the default domain is an IP address
+                // We know if the default domain is not an IP address and the current domain is, it won't suffix match
+                // If it is an IP Address, we should treat it only if it matches the host exactly
+                // We determine the canonical IP format before comparing because IPv6 could be represented in multiple formats
+                if (m_defaultDomainIsIPAddress) {
+                    String realDomainCanonical = String(BlackBerry::Platform::getCanonicalIPFormat(realDomain.utf8().data()).c_str());
+                    if (realDomainCanonical.isEmpty() || realDomainCanonical != m_defaultCookieHost)
+                        LOG_AND_DELETE("Invalid cookie %s (domain): domain is IP but does not match host's IP", cookie.ascii().data());
+                    realDomain = realDomainCanonical;
+                    isIPAddress = true;
+                } else {
+                    // The request host should domain match the Domain attribute.
+                    // Domain string starts with a dot, so a.b.com should domain match .a.b.com.
+                    // add a "." at beginning of host name, because it can handle many cases such as
+                    // a.b.com matches b.com, a.b.com matches .B.com and a.b.com matches .A.b.Com
+                    // and so on.
+                    // We also have to make a special case for IP addresses. If a website tries to set
+                    // a cookie to 61.97, that domain is not an IP address and will end with the m_defaultCookieHost
+                    if (!m_defaultCookieHost.endsWith(realDomain, false))
+                        LOG_AND_DELETE("Invalid cookie %s (domain): it does not domain match the host", cookie.ascii().data());
+                    // We should check for an embedded dot in the portion of string in the host not in the domain
+                    // but to match firefox behaviour we do not.
 
-                res->setDomain(realDomain);
+                    // Check whether the domain is a top level domain, if it is throw it out
+                    // http://publicsuffix.org/list/
+                    if (BlackBerry::Platform::isTopLevelDomain(realDomain.utf8().data()))
+                        LOG_AND_DELETE("Invalid cookie %s (domain): it did not pass the top level domain check", cookie.ascii().data());
+                }
+                res->setDomain(realDomain, isIPAddress);
             } else
                 LOG_AND_DELETE("Invalid cookie %s (domain)", cookie.ascii().data());
             break;
@@ -363,7 +385,7 @@
 
     // If no domain was provided, set it to the host
     if (!res->domain())
-        res->setDomain(m_defaultCookieURL.host());
+        res->setDomain(m_defaultCookieHost, m_defaultDomainIsIPAddress);
 
     // According to the Cookie Specificaiton (RFC6265, section 4.1.2.4 and 5.2.4, http://tools.ietf.org/html/rfc6265),
     // If no path was provided or the first character of the path value is not '/', set it to the host's path

Modified: trunk/Source/WebCore/platform/blackberry/CookieParser.h (127149 => 127150)


--- trunk/Source/WebCore/platform/blackberry/CookieParser.h	2012-08-30 16:08:27 UTC (rev 127149)
+++ trunk/Source/WebCore/platform/blackberry/CookieParser.h	2012-08-30 16:12:13 UTC (rev 127150)
@@ -50,6 +50,8 @@
     ParsedCookie* parseOneCookie(const String& cookie, unsigned start, unsigned end, double curTime);
 
     KURL m_defaultCookieURL;
+    String m_defaultCookieHost;
+    bool m_defaultDomainIsIPAddress;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/blackberry/ParsedCookie.cpp (127149 => 127150)


--- trunk/Source/WebCore/platform/blackberry/ParsedCookie.cpp	2012-08-30 16:08:27 UTC (rev 127149)
+++ trunk/Source/WebCore/platform/blackberry/ParsedCookie.cpp	2012-08-30 16:12:13 UTC (rev 127150)
@@ -45,6 +45,7 @@
     , m_isHttpOnly(false)
     , m_isSession(true)
     , m_isForceExpired(false)
+    , m_domainIsIPAddress(false)
 {
 }
 
@@ -61,6 +62,7 @@
     , m_isHttpOnly(isHttpOnly)
     , m_isSession(false)
     , m_isForceExpired(false)
+    , m_domainIsIPAddress(false)
 {
 }
 
@@ -77,6 +79,7 @@
     , m_isHttpOnly(cookie->m_isHttpOnly)
     , m_isSession(cookie->m_isSession)
     , m_isForceExpired(cookie->m_isForceExpired)
+    , m_domainIsIPAddress(cookie->m_domainIsIPAddress)
 {
 }
 

Modified: trunk/Source/WebCore/platform/blackberry/ParsedCookie.h (127149 => 127150)


--- trunk/Source/WebCore/platform/blackberry/ParsedCookie.h	2012-08-30 16:08:27 UTC (rev 127149)
+++ trunk/Source/WebCore/platform/blackberry/ParsedCookie.h	2012-08-30 16:12:13 UTC (rev 127150)
@@ -63,7 +63,7 @@
     void setPath(const String& path) { m_path = path; }
 
     const String& domain() const { return m_domain; }
-    void setDomain(const String& domain) { m_domain = domain.lower(); }
+    void setDomain(const String& domain, bool domainIsIPAddress = false) { m_domain = domain.lower(); m_domainIsIPAddress = domainIsIPAddress; }
 
     const String& protocol() const { return m_protocol; }
     void setProtocol(const String& protocol) { m_protocol = protocol; }
@@ -90,6 +90,7 @@
     bool hasExpired() const;
     bool isForceExpired() const { return m_isForceExpired; }
     bool isUnderSizeLimit() const;
+    bool domainIsIPAddress() const { return m_domainIsIPAddress; }
 
     String toString() const;
     String toNameValuePair() const;
@@ -110,6 +111,7 @@
     bool m_isHttpOnly;
     bool m_isSession;
     bool m_isForceExpired;
+    bool m_domainIsIPAddress;
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to