Stop rejecting cookies which have a domain that matches a TLD

... but only if the host it came from is an EXACT match. Also only apply
the cookie if the url is an EXACT match.

[ChangeLog][QtNetwork][QNetworkCookieJar] Cookies will no longer be
rejected when the domain matches a TLD. However (to avoid problems
with TLDs), such cookies are only accepted, or sent, when the host name
matches exactly.

Task-number: QTBUG-52040
Change-Id: Ic2ebd9211c48891beb669032591234b57713c31d
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
bb10
Mårten Nordheim 2017-12-14 11:49:19 +01:00
parent 2677ad78e6
commit 51e14787d5
2 changed files with 48 additions and 1 deletions

View File

@ -241,6 +241,17 @@ QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const
if ((*it).isSecure() && !isEncrypted)
continue;
QString domain = it->domain();
if (domain.startsWith(QLatin1Char('.'))) /// Qt6?: remove when compliant with RFC6265
domain = domain.mid(1);
#if QT_CONFIG(topleveldomain)
if (qIsEffectiveTLD(domain) && url.host() != domain)
continue;
#else
if (!domain.contains(QLatin1Char('.')) && url.host() != domain)
continue;
#endif // topleveldomain
// insert this cookie into result, sorted by path
QList<QNetworkCookie>::Iterator insertIt = result.begin();
while (insertIt != result.end()) {
@ -340,6 +351,11 @@ bool QNetworkCookieJar::validateCookie(const QNetworkCookie &cookie, const QUrl
if (domain.startsWith(QLatin1Char('.')))
domain = domain.mid(1);
// We shouldn't reject if:
// "[...] the domain-attribute is identical to the canonicalized request-host"
// https://tools.ietf.org/html/rfc6265#section-5.3 step 5
if (host == domain)
return true;
#if QT_CONFIG(topleveldomain)
// the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2
// redundant; the "leading dot" rule has been relaxed anyway, see QNetworkCookie::normalize()

View File

@ -164,7 +164,9 @@ void tst_QNetworkCookieJar::setCookiesFromUrl_data()
result.clear();
preset.clear();
cookie.setDomain(".foo.ck");
QTest::newRow("effective-tld2-denied") << preset << cookie << "http://foo.ck" << result << false;
result += cookie;
QTest::newRow("effective-tld2-accepted2") << preset << cookie << "http://foo.ck" << result << true;
result.clear();
QTest::newRow("effective-tld2-denied2") << preset << cookie << "http://www.foo.ck" << result << false;
QTest::newRow("effective-tld2-denied3") << preset << cookie << "http://www.anything.foo.ck" << result << false;
cookie.setDomain(".www.ck");
@ -208,6 +210,22 @@ void tst_QNetworkCookieJar::setCookiesFromUrl_data()
preset.clear();
cookie.setDomain(".com.");
QTest::newRow("rfc2109-4.3.2-ex3-2") << preset << cookie << "http://x.foo.com" << result << false;
// When using a TLD as a hostname the hostname should still get cookies (QTBUG-52040)
// ... and nothing else should get the cookies.
result.clear();
preset.clear();
cookie.setPath("/");
cookie.setDomain(".support");
result += cookie;
QTest::newRow("TLD-as-domain-accepted") << preset << cookie << "http://support" << result << true;
result.clear();
QTest::newRow("TLD-as-domain-rejected") << preset << cookie << "http://a.support" << result << false;
// Now test with no domain in the cookie, use the domain from the url (matching TLD)
cookie.setDomain("support");
result += cookie;
cookie.setDomain("");
QTest::newRow("TLD-as-domain-accepted2") << preset << cookie << "http://support" << result << true;
}
void tst_QNetworkCookieJar::setCookiesFromUrl()
@ -351,6 +369,19 @@ void tst_QNetworkCookieJar::cookiesForUrl_data()
result.clear();
result += rootCookie;
QTest::newRow("root-path-match") << allCookies << "http://qt-project.org" << result;
// Domain in cookie happens to match a TLD
allCookies.clear();
QNetworkCookie tldCookie;
tldCookie.setDomain(".support");
tldCookie.setName("a");
tldCookie.setValue("b");
allCookies += tldCookie;
result.clear();
result += tldCookie;
QTest::newRow("tld-cookie-match") << allCookies << "http://support/" << result;
result.clear();
QTest::newRow("tld-cookie-no-match") << allCookies << "http://a.support/" << result;
}
void tst_QNetworkCookieJar::cookiesForUrl()