Bug 1666678 - [cookie] rejected cookie when domain have ipv6 address r=baku

Differential Revision: https://phabricator.services.mozilla.com/D91246
This commit is contained in:
Valentin Gosu 2020-11-04 09:44:23 +00:00
Родитель 171ca8fd0a
Коммит ad416f2616
6 изменённых файлов: 86 добавлений и 17 удалений

Просмотреть файл

@ -7177,20 +7177,24 @@ uint64_t nsContentUtils::GetInnerWindowID(nsILoadGroup* aLoadGroup) {
return inner ? inner->WindowID() : 0;
}
nsresult nsContentUtils::GetHostOrIPv6WithBrackets(nsIURI* aURI,
nsCString& aHost) {
aHost.Truncate();
nsresult rv = aURI->GetHost(aHost);
if (NS_FAILED(rv)) { // Some URIs do not have a host
return rv;
}
static void MaybeFixIPv6Host(nsACString& aHost) {
if (aHost.FindChar(':') != -1) { // Escape IPv6 address
MOZ_ASSERT(!aHost.Length() ||
(aHost[0] != '[' && aHost[aHost.Length() - 1] != ']'));
aHost.Insert('[', 0);
aHost.Append(']');
}
}
nsresult nsContentUtils::GetHostOrIPv6WithBrackets(nsIURI* aURI,
nsACString& aHost) {
aHost.Truncate();
nsresult rv = aURI->GetHost(aHost);
if (NS_FAILED(rv)) { // Some URIs do not have a host
return rv;
}
MaybeFixIPv6Host(aHost);
return NS_OK;
}
@ -7206,6 +7210,17 @@ nsresult nsContentUtils::GetHostOrIPv6WithBrackets(nsIURI* aURI,
return NS_OK;
}
nsresult nsContentUtils::GetHostOrIPv6WithBrackets(nsIPrincipal* aPrincipal,
nsACString& aHost) {
nsresult rv = aPrincipal->GetAsciiHost(aHost);
if (NS_FAILED(rv)) { // Some URIs do not have a host
return rv;
}
MaybeFixIPv6Host(aHost);
return NS_OK;
}
CallState nsContentUtils::CallOnAllRemoteChildren(
MessageBroadcaster* aManager,
const std::function<CallState(BrowserParent*)>& aCallback) {

Просмотреть файл

@ -2809,7 +2809,9 @@ class nsContentUtils {
* otherwise it just outputs the hostname in aHost.
*/
static nsresult GetHostOrIPv6WithBrackets(nsIURI* aURI, nsAString& aHost);
static nsresult GetHostOrIPv6WithBrackets(nsIURI* aURI, nsCString& aHost);
static nsresult GetHostOrIPv6WithBrackets(nsIURI* aURI, nsACString& aHost);
static nsresult GetHostOrIPv6WithBrackets(nsIPrincipal* aPrincipal,
nsACString& aHost);
/*
* Call the given callback on all remote children of the given top-level

Просмотреть файл

@ -91,7 +91,7 @@ nsresult CookieCommons::GetBaseDomain(nsIEffectiveTLDService* aTLDService,
// aHostURI is either an IP address, an alias such as 'localhost', an eTLD
// such as 'co.uk', or the empty string. use the host as a key in such
// cases.
rv = aHostURI->GetAsciiHost(aBaseDomain);
rv = nsContentUtils::GetHostOrIPv6WithBrackets(aHostURI, aBaseDomain);
}
NS_ENSURE_SUCCESS(rv, rv);
@ -114,7 +114,7 @@ nsresult CookieCommons::GetBaseDomain(nsIPrincipal* aPrincipal,
// for historical reasons we use ascii host for file:// URLs.
if (aPrincipal->SchemeIs("file")) {
return aPrincipal->GetAsciiHost(aBaseDomain);
return nsContentUtils::GetHostOrIPv6WithBrackets(aPrincipal, aBaseDomain);
}
return aPrincipal->GetBaseDomain(aBaseDomain);

Просмотреть файл

@ -301,7 +301,7 @@ CookieService::GetCookieStringFromDocument(Document* aDocument,
}
nsAutoCString hostFromURI;
rv = principal->GetAsciiHost(hostFromURI);
rv = nsContentUtils::GetHostOrIPv6WithBrackets(principal, hostFromURI);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_OK;
}
@ -538,9 +538,7 @@ CookieService::SetCookieStringFromHttp(nsIURI* aHostURI,
CookieCommons::GetCookieJarSettings(aChannel);
nsAutoCString hostFromURI;
aHostURI->GetHost(hostFromURI);
rv = NormalizeHost(hostFromURI);
NS_ENSURE_SUCCESS(rv, NS_OK);
nsContentUtils::GetHostOrIPv6WithBrackets(aHostURI, hostFromURI);
nsAutoCString baseDomainFromURI;
rv = CookieCommons::GetBaseDomainFromHost(mTLDService, hostFromURI,
@ -860,7 +858,7 @@ void CookieService::GetCookiesForURI(
nsresult rv = CookieCommons::GetBaseDomain(mTLDService, aHostURI, baseDomain,
requireHostMatch);
if (NS_SUCCEEDED(rv)) {
rv = aHostURI->GetAsciiHost(hostFromURI);
rv = nsContentUtils::GetHostOrIPv6WithBrackets(aHostURI, hostFromURI);
}
if (NS_SUCCEEDED(rv)) {
rv = aHostURI->GetFilePath(pathFromURI);
@ -1697,7 +1695,7 @@ bool CookieService::CheckDomain(CookieStruct& aCookieData, nsIURI* aHostURI,
// get host from aHostURI
nsAutoCString hostFromURI;
aHostURI->GetAsciiHost(hostFromURI);
nsContentUtils::GetHostOrIPv6WithBrackets(aHostURI, hostFromURI);
// if a domain is given, check the host has permission
if (!aCookieData.host().IsEmpty()) {

Просмотреть файл

@ -0,0 +1,52 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Test that channels with different LoadInfo
* are stored in separate namespaces ("cookie jars")
*/
"use strict";
let ip = "[::1]";
XPCOMUtils.defineLazyGetter(this, "URL", function() {
return `http://${ip}:${httpserver.identity.primaryPort}/`;
});
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
let httpserver = new HttpServer();
function cookieSetHandler(metadata, response) {
response.setStatusLine(metadata.httpVersion, 200, "Ok");
response.setHeader(
"Set-Cookie",
`Set-Cookie: T1=T2; path=/; SameSite=Lax; domain=${ip}; httponly`,
false
);
response.setHeader("Content-Type", "text/html");
response.setHeader("Content-Length", "2");
response.bodyOutputStream.write("Ok", "Ok".length);
}
add_task(async function test_cookie_ipv6() {
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
Services.prefs.setBoolPref(
"network.cookieJarSettings.unblocked_for_testing",
true
);
httpserver.registerPathHandler("/", cookieSetHandler);
httpserver._start(-1, ip);
var chan = NetUtil.newChannel({
uri: URL,
loadUsingSystemPrincipal: true,
});
let req = await new Promise(resolve => {
chan.asyncOpen(new ChannelListener(resolve));
});
var cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
equal(cm.cookies.length, 1);
});

Просмотреть файл

@ -477,3 +477,5 @@ skip-if = asan || tsan || os == 'win' || os =='android'
skip-if = asan || tsan || os == 'win' || os =='android'
[test_http3_fatal_stream_error.js]
skip-if = asan || tsan || os == 'win' || os =='android'
[test_cookie_ipv6.js]