Bug 818340 - change third party cookie handling to block third party cookies from sites I haven't visited. (r=jdm, r=dolske)

--HG--
extra : rebase_source : f486f39feac1fb743edc920618bec29884d515f1
This commit is contained in:
Jonathan Mayer 2013-02-22 08:16:01 -08:00
parent 696cf350b6
commit 55b948dec0
44 changed files with 475 additions and 87 deletions

View File

@ -179,8 +179,8 @@ var gPrivacyPane = {
// select the remember forms history option
document.getElementById("browser.formfill.enable").value = true;
// select the accept cookies option
document.getElementById("network.cookie.cookieBehavior").value = 0;
// select the limit cookies option
document.getElementById("network.cookie.cookieBehavior").value = 3;
// select the cookie lifetime policy option
document.getElementById("network.cookie.lifetimePolicy").value = 0;
@ -363,9 +363,10 @@ var gPrivacyPane = {
* network.cookie.cookieBehavior
* - determines how the browser should handle cookies:
* 0 means enable all cookies
* 1 means reject third party cookies; see
* netwerk/cookie/src/nsCookieService.cpp for a hairier definition
* 1 means reject all third party cookies
* 2 means disable all cookies
* 3 means reject third party cookies unless at least one is already set for the eTLD
* see netwerk/cookie/src/nsCookieService.cpp for details
* network.cookie.lifetimePolicy
* - determines how long cookies are stored:
* 0 means keep cookies until they expire
@ -381,25 +382,20 @@ var gPrivacyPane = {
readAcceptCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
var acceptThirdParty = document.getElementById("acceptThirdParty");
var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel");
var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
var keepUntil = document.getElementById("keepUntil");
var menu = document.getElementById("keepCookiesUntil");
// enable the rest of the UI for anything other than "disable all cookies"
var acceptCookies = (pref.value != 2);
acceptThirdParty.disabled = !acceptCookies;
acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies;
keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies;
return acceptCookies;
},
readAcceptThirdPartyCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
return pref.value == 0;
},
/**
* Enables/disables the "keep until" label and menulist in response to the
* "accept cookies" checkbox being checked or unchecked.
@ -407,20 +403,50 @@ var gPrivacyPane = {
writeAcceptCookies: function ()
{
var accept = document.getElementById("acceptCookies");
var acceptThirdParty = document.getElementById("acceptThirdParty");
var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
// if we're enabling cookies, automatically check 'accept third party'
// if we're enabling cookies, automatically select 'accept third party from visited'
if (accept.checked)
acceptThirdParty.checked = true;
acceptThirdPartyMenu.selectedIndex = 1;
return accept.checked ? (acceptThirdParty.checked ? 0 : 1) : 2;
return accept.checked ? 3 : 2;
},
/**
* Converts between network.cookie.cookieBehavior and the third-party cookie UI
*/
readAcceptThirdPartyCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
switch (pref.value)
{
case 0:
return "always";
case 1:
return "never";
case 2:
return "never";
case 3:
return "visited";
default:
return undefined;
}
},
writeAcceptThirdPartyCookies: function ()
{
var accept = document.getElementById("acceptCookies");
var acceptThirdParty = document.getElementById("acceptThirdParty");
return accept.checked ? (acceptThirdParty.checked ? 0 : 1) : 2;
var accept = document.getElementById("acceptThirdPartyMenu").selectedItem;
switch (accept.value)
{
case "always":
return 0;
case "visited":
return 3;
case "never":
return 1;
default:
return undefined;
}
},
/**

View File

@ -170,11 +170,19 @@
label="&cookieExceptions.label;" accesskey="&cookieExceptions.accesskey;"
preference="pref.privacy.disable_button.cookie_exceptions"/>
</hbox>
<checkbox id="acceptThirdParty" label="&acceptThirdParty.label;" class="indent"
preference="network.cookie.cookieBehavior"
accesskey="&acceptThirdParty.accesskey;"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();"/>
<hbox id="acceptThirdPartyRow" class="indent">
<label id="acceptThirdPartyLabel" control="acceptThirdPartyMenu"
accesskey="&acceptThirdParty.pre.accesskey;">&acceptThirdParty.pre.label;</label>
<menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();">
<menupopup>
<menuitem label="&acceptThirdParty.always.label;" value="always"/>
<menuitem label="&acceptThirdParty.visited.label;" value="visited"/>
<menuitem label="&acceptThirdParty.never.label;" value="never"/>
</menupopup>
</menulist>
</hbox>
<hbox id="keepRow" class="indent">
<label id="keepUntil"
control="keepCookiesUntil"

View File

@ -15,8 +15,8 @@ function test() {
run_test_subset([
test_custom_retention("acceptCookies", "remember"),
test_custom_retention("acceptCookies", "custom"),
test_custom_retention("acceptThirdParty", "remember"),
test_custom_retention("acceptThirdParty", "custom"),
test_custom_retention("acceptThirdPartyMenu", "remember", "always"),
test_custom_retention("acceptThirdPartyMenu", "custom", "visited"),
test_custom_retention("keepCookiesUntil", "remember", 1),
test_custom_retention("keepCookiesUntil", "custom", 2),
test_custom_retention("keepCookiesUntil", "custom", 0),

View File

@ -59,7 +59,8 @@ function test_dependent_elements(win) {
});
let independents = [
win.document.getElementById("acceptCookies"),
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptThirdPartyLabel"),
win.document.getElementById("acceptThirdPartyMenu")
];
independents.forEach(function(control) {
ok(control, "the independent controls should exist");
@ -124,7 +125,8 @@ function test_dependent_cookie_elements(win) {
let pbautostart = win.document.getElementById("privateBrowsingAutoStart");
ok(pbautostart, "the private browsing auto-start checkbox should exist");
let controls = [
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptThirdPartyLabel"),
win.document.getElementById("acceptThirdPartyMenu"),
win.document.getElementById("keepUntil"),
win.document.getElementById("keepCookiesUntil"),
];
@ -210,18 +212,22 @@ function test_dependent_prefs(win) {
let controls = [
win.document.getElementById("rememberHistory"),
win.document.getElementById("rememberForms"),
win.document.getElementById("acceptCookies"),
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptCookies")
];
controls.forEach(function(control) {
ok(control, "the micro-management controls should exist");
});
let thirdPartyCookieMenu = win.document.getElementById("acceptThirdPartyMenu");
ok(thirdPartyCookieMenu, "the third-party cookie control should exist");
function expect_checked(checked) {
controls.forEach(function(control) {
is(control.checked, checked,
control.getAttribute("id") + " should " + (checked ? "not " : "") + "be checked");
});
is(thirdPartyCookieMenu.value == "always" || thirdPartyCookieMenu.value == "visited", checked, "third-party cookies should " + (checked ? "not " : "") + "be limited");
}
// controls should be checked in remember mode
@ -232,6 +238,8 @@ function test_dependent_prefs(win) {
// even if they're unchecked in custom mode
historymode.value = "custom";
controlChanged(historymode);
thirdPartyCookieMenu.value = "never";
controlChanged(thirdPartyCookieMenu);
controls.forEach(function(control) {
control.checked = false;
controlChanged(control);

View File

@ -182,8 +182,8 @@ var gPrivacyPane = {
// select the remember forms history option
document.getElementById("browser.formfill.enable").value = true;
// select the accept cookies option
document.getElementById("network.cookie.cookieBehavior").value = 0;
// select the limit cookies option
document.getElementById("network.cookie.cookieBehavior").value = 3;
// select the cookie lifetime policy option
document.getElementById("network.cookie.lifetimePolicy").value = 0;
@ -366,9 +366,10 @@ var gPrivacyPane = {
* network.cookie.cookieBehavior
* - determines how the browser should handle cookies:
* 0 means enable all cookies
* 1 means reject third party cookies; see
* netwerk/cookie/src/nsCookieService.cpp for a hairier definition
* 1 means reject all third party cookies
* 2 means disable all cookies
* 3 means reject third party cookies unless at least one is already set for the eTLD
* see netwerk/cookie/src/nsCookieService.cpp for details
* network.cookie.lifetimePolicy
* - determines how long cookies are stored:
* 0 means keep cookies until they expire
@ -384,25 +385,20 @@ var gPrivacyPane = {
readAcceptCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
var acceptThirdParty = document.getElementById("acceptThirdParty");
var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel");
var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
var keepUntil = document.getElementById("keepUntil");
var menu = document.getElementById("keepCookiesUntil");
// enable the rest of the UI for anything other than "disable all cookies"
var acceptCookies = (pref.value != 2);
acceptThirdParty.disabled = !acceptCookies;
acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies;
keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies;
return acceptCookies;
},
readAcceptThirdPartyCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
return pref.value == 0;
},
/**
* Enables/disables the "keep until" label and menulist in response to the
* "accept cookies" checkbox being checked or unchecked.
@ -410,20 +406,50 @@ var gPrivacyPane = {
writeAcceptCookies: function ()
{
var accept = document.getElementById("acceptCookies");
var acceptThirdParty = document.getElementById("acceptThirdParty");
var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
// if we're enabling cookies, automatically check 'accept third party'
// if we're enabling cookies, automatically select 'accept third party from visited'
if (accept.checked)
acceptThirdParty.checked = true;
acceptThirdPartyMenu.selectedIndex = 1;
return accept.checked ? (acceptThirdParty.checked ? 0 : 1) : 2;
return accept.checked ? 3 : 2;
},
/**
* Converts between network.cookie.cookieBehavior and the third-party cookie UI
*/
readAcceptThirdPartyCookies: function ()
{
var pref = document.getElementById("network.cookie.cookieBehavior");
switch (pref.value)
{
case 0:
return "always";
case 1:
return "never";
case 2:
return "never";
case 3:
return "visited";
default:
return undefined;
}
},
writeAcceptThirdPartyCookies: function ()
{
var accept = document.getElementById("acceptCookies");
var acceptThirdParty = document.getElementById("acceptThirdParty");
return accept.checked ? (acceptThirdParty.checked ? 0 : 1) : 2;
var accept = document.getElementById("acceptThirdPartyMenu").selectedItem;
switch (accept.value)
{
case "always":
return 0;
case "visited":
return 3;
case "never":
return 1;
default:
return undefined;
}
},
/**
@ -503,7 +529,7 @@ var gPrivacyPane = {
var settingsButton = document.getElementById("clearDataSettings");
var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown");
settingsButton.disabled = !sanitizeOnShutdownPref.value;
settingsButton.disabled = !sanitizeOnShutdownPref.value;
}
};

View File

@ -183,12 +183,23 @@
label="&cookieExceptions.label;" accesskey="&cookieExceptions.accesskey;"
preference="pref.privacy.disable_button.cookie_exceptions"/>
</hbox>
<checkbox id="acceptThirdParty" label="&acceptThirdParty.label;" class="indent"
preference="network.cookie.cookieBehavior"
accesskey="&acceptThirdParty.accesskey;"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();"/>
<hbox id="acceptThirdPartyRow" class="indent">
<hbox id="acceptThirdPartyBox" align="center">
<label id="acceptThirdPartyLabel" control="acceptThirdPartyMenu"
accesskey="&acceptThirdParty.pre.accesskey;">&acceptThirdParty.pre.label;</label>
<menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior"
onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();"
onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();">
<menupopup>
<menuitem label="&acceptThirdParty.always.label;" value="always"/>
<menuitem label="&acceptThirdParty.visited.label;" value="visited"/>
<menuitem label="&acceptThirdParty.never.label;" value="never"/>
</menupopup>
</menulist>
</hbox>
</hbox>
<hbox id="keepRow" class="indent">
<hbox id="keepBox" align="center">
<label id="keepUntil"

View File

@ -2,7 +2,12 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
waitForExplicitFinish();
// Allow all cookies, then actually set up the test
SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, initTest);
}
function initTest() {
const searchTerm = "example";
const dummyTerm = "elpmaxe";

View File

@ -163,6 +163,9 @@ var tests = [
},
function test_all_sites_permission() {
// apply the old default of allowing all cookies
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
// there should be no user-set pref for cookie behavior
is(Services.prefs.getIntPref("network.cookie.cookieBehavior"), PERM_UNKNOWN,
"network.cookie.cookieBehavior is expected default");

View File

@ -16,8 +16,8 @@ function test() {
run_test_subset([
test_custom_retention("acceptCookies", "remember"),
test_custom_retention("acceptCookies", "custom"),
test_custom_retention("acceptThirdParty", "remember"),
test_custom_retention("acceptThirdParty", "custom"),
test_custom_retention("acceptThirdPartyMenu", "remember", "always"),
test_custom_retention("acceptThirdPartyMenu", "custom", "visited"),
test_custom_retention("keepCookiesUntil", "remember", 1),
test_custom_retention("keepCookiesUntil", "custom", 2),
test_custom_retention("keepCookiesUntil", "custom", 0),

View File

@ -69,7 +69,8 @@ function test_dependent_elements(win) {
});
let independents = [
win.document.getElementById("acceptCookies"),
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptThirdPartyLabel"),
win.document.getElementById("acceptThirdPartyMenu")
];
independents.forEach(function(control) {
ok(control, "the independent controls should exist");
@ -133,7 +134,8 @@ function test_dependent_cookie_elements(win) {
let pbautostart = win.document.getElementById("privateBrowsingAutoStart");
ok(pbautostart, "the private browsing auto-start checkbox should exist");
let controls = [
win.document.getElementById("acceptThirdParty"),
win.document.getElementById("acceptThirdPartyLabel"),
win.document.getElementById("acceptThirdPartyMenu"),
win.document.getElementById("keepUntil"),
win.document.getElementById("keepCookiesUntil"),
];
@ -220,17 +222,21 @@ function test_dependent_prefs(win) {
win.document.getElementById("rememberHistory"),
win.document.getElementById("rememberForms"),
win.document.getElementById("acceptCookies"),
win.document.getElementById("acceptThirdParty"),
];
controls.forEach(function(control) {
ok(control, "the micro-management controls should exist");
});
let thirdPartyCookieMenu = win.document.getElementById("acceptThirdPartyMenu");
ok(thirdPartyCookieMenu, "the third-party cookie control should exist");
function expect_checked(checked) {
controls.forEach(function(control) {
is(control.checked, checked,
control.getAttribute("id") + " should " + (checked ? "not " : "") + "be checked");
});
is(thirdPartyCookieMenu.value == "always" || thirdPartyCookieMenu.value == "visited", checked, "third-party cookies should " + (checked ? "not " : "") + "be limited");
}
// controls should be checked in remember mode
@ -241,6 +247,8 @@ function test_dependent_prefs(win) {
// even if they're unchecked in custom mode
historymode.value = "custom";
controlChanged(historymode);
thirdPartyCookieMenu.value = "never";
controlChanged(thirdPartyCookieMenu);
controls.forEach(function(control) {
control.checked = false;
controlChanged(control);

View File

@ -27,8 +27,11 @@
<!ENTITY acceptCookies.label "Accept cookies from sites">
<!ENTITY acceptCookies.accesskey "A">
<!ENTITY acceptThirdParty.label "Accept third-party cookies">
<!ENTITY acceptThirdParty.accesskey "c">
<!ENTITY acceptThirdParty.pre.label "Accept third-party cookies:">
<!ENTITY acceptThirdParty.pre.accesskey "c">
<!ENTITY acceptThirdParty.always.label "Always">
<!ENTITY acceptThirdParty.never.label "Never">
<!ENTITY acceptThirdParty.visited.label "From visited">
<!ENTITY keepUntil.label "Keep until:">
<!ENTITY keepUntil.accesskey "K">

View File

@ -6,7 +6,7 @@
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="gen.next()">
<body onload="initTest()">
<p id="display">
<iframe id=loader></iframe>
</p>
@ -20,13 +20,23 @@ const runPreflightTests = 1;
const runCookieTests = 1;
const runRedirectTests = 1;
SimpleTest.waitForExplicitFinish();
var gen;
window.addEventListener("message", function(e) {
gen.send(e.data);
}, false);
function initTest() {
SimpleTest.waitForExplicitFinish();
// Allow all cookies, then do the actual test initialization
SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, initTestCallback);
}
gen = runTest();
function initTestCallback() {
window.addEventListener("message", function(e) {
gen.send(e.data);
}, false);
gen = runTest();
gen.next()
}
function runTest() {
var loader = document.getElementById('loader');

View File

@ -595,7 +595,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583
}, parseInt(8000*stress_factor));
}
function doTest(test_id)
function doTest()
{
// Allow all cookies, then run the actual test
SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, doTestCallback);
}
function doTestCallback()
{
oldPrefVal = SpecialPowers.getBoolPref("dom.server-events.enabled");
SpecialPowers.setBoolPref("dom.server-events.enabled", true);

View File

@ -20,6 +20,11 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
function runTests() {
// Allow all cookies, then run the actual tests
SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, runTestsCallback);
}
function runTestsCallback() {
var pluginElement1 = document.getElementById("plugin1");
var pluginElement2 = document.getElementById("plugin2");

View File

@ -216,6 +216,24 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI,
*aResult = false;
break;
case nsICookiePermission::ACCESS_LIMIT_THIRD_PARTY:
mThirdPartyUtil->IsThirdPartyChannel(aChannel, aURI, &isThirdParty);
// If it's third party, check whether cookies are already set
if (isThirdParty) {
nsresult rv;
nsCOMPtr<nsICookieManager2> cookieManager = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
*aResult = false;
break;
}
uint32_t priorCookieCount = 0;
nsAutoCString hostFromURI;
aURI->GetHost(hostFromURI);
cookieManager->CountCookiesFromHost(hostFromURI, &priorCookieCount);
*aResult = priorCookieCount != 0;
}
break;
default:
// the permission manager has nothing to say about this cookie -
// so, we apply the default prefs to it.

View File

@ -152,6 +152,11 @@ try {
}
SpecialPowers.setBoolPref('browser.mozApps.installer.dry_run', true);
var previousCookiePrefValue = SpecialPowers.getIntPref('network.cookie.cookieBehavior');
SpecialPowers.setIntPref('network.cookie.cookieBehavior', 0);
permManager.addFromPrincipal(window.document.nodePrincipal, "webapps-manage",
Ci.nsIPermissionManager.ALLOW_ACTION);
@ -195,6 +200,7 @@ function checkCookie() {
"Number of cookies should not have changed");
SpecialPowers.setBoolPref('browser.mozApps.installer.dry_run', previousDryRunValue);
SpecialPowers.setIntPref('network.cookie.cookieBehavior', previousCookiePrefValue);
permManager.removeFromPrincipal(window.document.nodePrincipal, "webapps-manage",
Ci.nsIPermissionManager.ALLOW_ACTION);

View File

@ -104,6 +104,13 @@ function do_load_profile(generator) {
service.observe(null, "profile-do-change", "");
}
// Set a single session cookie using http and test the cookie count
// against 'expected'
function do_set_single_http_cookie(uri, channel, expected) {
Services.cookies.setCookieStringFromHttp(uri, null, null, "foo=bar", null, channel);
do_check_eq(Services.cookiemgr.countCookiesFromHost(uri.host), expected);
}
// Set four cookies; with & without channel, http and non-http; and test
// the cookie count against 'expected' after each set.
function do_set_cookies(uri, channel, session, expected) {

View File

@ -8,6 +8,9 @@ function run_test() {
cm.removeAll();
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
// test that variants of 'baz.com' get normalized appropriately, but that
// malformed hosts are rejected
cm.add("baz.com", "/", "foo", "bar", false, false, true, expiry);

View File

@ -36,6 +36,9 @@ function do_run_test() {
// Set up a profile.
this.profile = do_get_profile();
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
// Get the cookie file and the backup file.
do_check_false(do_get_cookie_file(profile).exists());
do_check_false(do_get_backup_file(profile).exists());

View File

@ -21,6 +21,9 @@ function do_run_test() {
// Set up a profile.
let profile = do_get_profile();
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
// Start the cookieservice.
Services.cookies;

View File

@ -21,6 +21,9 @@ function do_run_test() {
// Set up a profile.
let profile = do_get_profile();
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
// Start the cookieservice, to force creation of a database.
Services.cookies;

View File

@ -38,6 +38,9 @@ function do_run_test() {
// Set up a profile.
this.profile = do_get_profile();
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
// Get the cookie file and the backup file.
this.cookieFile = profile.clone();
cookieFile.append("cookies.sqlite");

View File

@ -50,7 +50,17 @@ function run_test() {
do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]);
Services.cookies.removeAll();
// Test per-site 3rd party cookies with cookies enabled
// test with third party cookies limited
Services.prefs.setIntPref("network.cookie.cookieBehavior", 3);
do_set_cookies(uri1, channel1, true, [0, 1, 2, 3]);
Services.cookies.removeAll();
do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]);
Services.cookies.removeAll();
do_set_single_http_cookie(uri1, channel1, 1);
do_set_cookies(uri1, channel2, true, [2, 3, 4, 5]);
Services.cookies.removeAll();
// Test per-site 3rd party cookie blocking with cookies enabled
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
var kPermissionType = "cookie";
var ALLOW_FIRST_PARTY_ONLY = 9;
@ -61,7 +71,7 @@ function run_test() {
do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]);
Services.cookies.removeAll();
// Test per-site 3rd party cookies with 3rd party cookies disabled
// Test per-site 3rd party cookie blocking with 3rd party cookies disabled
Services.prefs.setIntPref("network.cookie.cookieBehavior", 1);
do_set_cookies(uri1, channel1, true, [0, 1, 1, 2]);
Services.cookies.removeAll();
@ -71,5 +81,67 @@ function run_test() {
Services.cookies.removeAll();
do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]);
Services.cookies.removeAll();
// Test per-site 3rd party cookie blocking with 3rd party cookies limited
Services.prefs.setIntPref("network.cookie.cookieBehavior", 3);
do_set_cookies(uri1, channel1, true, [0, 1, 1, 2]);
Services.cookies.removeAll();
// No preference has been set for uri2, but it should act as if
// LIMIT_THIRD_PARTY has been set
do_set_cookies(uri2, channel2, true, [0, 1, 2, 3]);
Services.cookies.removeAll();
do_set_single_http_cookie(uri2, channel2, 1);
do_set_cookies(uri2, channel2, true, [2, 3, 4, 5]);
Services.cookies.removeAll();
do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]);
Services.cookies.removeAll();
do_set_single_http_cookie(uri1, channel1, 1);
do_set_cookies(uri1, channel2, true, [1, 1, 1, 1]);
Services.cookies.removeAll();
// Test per-site 3rd party cookie limiting with cookies enabled
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
var kPermissionType = "cookie";
var LIMIT_THIRD_PARTY = 10;
// LIMIT_THIRD_PARTY overrides
Services.permissions.add(uri1, kPermissionType, LIMIT_THIRD_PARTY);
do_set_cookies(uri1, channel1, true, [0, 1, 2, 3]);
Services.cookies.removeAll();
do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]);
Services.cookies.removeAll();
do_set_single_http_cookie(uri1, channel1, 1);
do_set_cookies(uri1, channel2, true, [2, 3, 4, 5]);
Services.cookies.removeAll();
// Test per-site 3rd party cookie limiting with 3rd party cookies disabled
Services.prefs.setIntPref("network.cookie.cookieBehavior", 1);
do_set_cookies(uri1, channel1, true, [0, 1, 2, 3]);
Services.cookies.removeAll();
// No preference has been set for uri2, but it should act as if
// ALLOW_FIRST_PARTY_ONLY has been set
do_set_cookies(uri2, channel2, true, [0, 1, 1, 2]);
Services.cookies.removeAll();
do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]);
Services.cookies.removeAll();
do_set_single_http_cookie(uri1, channel1, 1);
do_set_cookies(uri1, channel2, true, [2, 3, 4, 5]);
Services.cookies.removeAll();
// Test per-site 3rd party cookie limiting with 3rd party cookies limited
Services.prefs.setIntPref("network.cookie.cookieBehavior", 3);
do_set_cookies(uri1, channel1, true, [0, 1, 2, 3]);
Services.cookies.removeAll();
// No preference has been set for uri2, but it should act as if
// LIMIT_THIRD_PARTY has been set
do_set_cookies(uri2, channel2, true, [0, 1, 2, 3]);
Services.cookies.removeAll();
do_set_single_http_cookie(uri2, channel2, 1);
do_set_cookies(uri2, channel2, true, [2, 3, 4, 5]);
Services.cookies.removeAll();
do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]);
Services.cookies.removeAll();
do_set_single_http_cookie(uri1, channel1, 1);
do_set_cookies(uri1, channel2, true, [2, 3, 4, 5]);
Services.cookies.removeAll();
}

View File

@ -1286,7 +1286,13 @@ pref("network.proxy.socks_remote_dns", false);
pref("network.proxy.no_proxies_on", "localhost, 127.0.0.1");
pref("network.proxy.failover_timeout", 1800); // 30 minutes
pref("network.online", true); //online/offline
pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
pref("network.cookie.cookieBehavior", 3); // 0-Accept, 1-dontAcceptForeign, 2-dontUse, 3-limitForeign
#ifdef ANDROID
pref("network.cookie.cookieBehavior", 0); // Keep the old default of accepting all cookies
#endif
#ifdef MOZ_WIDGET_GONK
pref("network.cookie.cookieBehavior", 0); // Keep the old default of accepting all cookies
#endif
pref("network.cookie.thirdparty.sessionOnly", false);
pref("network.cookie.lifetimePolicy", 0); // accept normally, 1-askBeforeAccepting, 2-acceptForSession,3-acceptForNDays
pref("network.cookie.alwaysAcceptSessionCookies", false);

View File

@ -22,6 +22,7 @@ namespace net {
static const int32_t BEHAVIOR_ACCEPT = 0;
static const int32_t BEHAVIOR_REJECTFOREIGN = 1;
static const int32_t BEHAVIOR_REJECT = 2;
static const int32_t BEHAVIOR_LIMITFOREIGN = 3;
// Pref string constants
static const char kPrefCookieBehavior[] = "network.cookie.cookieBehavior";
@ -80,7 +81,7 @@ CookieServiceChild::PrefChanged(nsIPrefBranch *aPrefBranch)
int32_t val;
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookieBehavior, &val)))
mCookieBehavior =
val >= BEHAVIOR_ACCEPT && val <= BEHAVIOR_REJECT ? val : BEHAVIOR_ACCEPT;
val >= BEHAVIOR_ACCEPT && val <= BEHAVIOR_LIMITFOREIGN ? val : BEHAVIOR_ACCEPT;
bool boolval;
if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kPrefThirdPartySession, &boolval)))
@ -95,7 +96,7 @@ CookieServiceChild::PrefChanged(nsIPrefBranch *aPrefBranch)
bool
CookieServiceChild::RequireThirdPartyCheck()
{
return mCookieBehavior == BEHAVIOR_REJECTFOREIGN || mThirdPartySession;
return mCookieBehavior == BEHAVIOR_REJECTFOREIGN || mCookieBehavior == BEHAVIOR_LIMITFOREIGN || mThirdPartySession;
}
nsresult

View File

@ -95,9 +95,11 @@ static const uint32_t kMaxBytesPerCookie = 4096;
static const uint32_t kMaxBytesPerPath = 1024;
// behavior pref constants
static const uint32_t BEHAVIOR_ACCEPT = 0;
static const uint32_t BEHAVIOR_REJECTFOREIGN = 1;
static const uint32_t BEHAVIOR_REJECT = 2;
static const uint32_t BEHAVIOR_ACCEPT = 0; // allow all cookies
static const uint32_t BEHAVIOR_REJECTFOREIGN = 1; // reject all third-party cookies
static const uint32_t BEHAVIOR_REJECT = 2; // reject all cookies
static const uint32_t BEHAVIOR_LIMITFOREIGN = 3; // reject third-party cookies unless the
// eTLD already has at least one cookie
// pref string constants
static const char kPrefCookieBehavior[] = "network.cookie.cookieBehavior";
@ -1694,7 +1696,7 @@ nsCookieService::PrefChanged(nsIPrefBranch *aPrefBranch)
{
int32_t val;
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookieBehavior, &val)))
mCookieBehavior = (uint8_t) LIMIT(val, 0, 2, 0);
mCookieBehavior = (uint8_t) LIMIT(val, 0, 3, 0);
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefMaxNumberOfCookies, &val)))
mMaxNumberOfCookies = (uint16_t) LIMIT(val, 1, 0xFFFF, kMaxNumberOfCookies);
@ -3244,6 +3246,20 @@ nsCookieService::CheckPrefs(nsIURI *aHostURI,
}
return STATUS_ACCEPTED;
case nsICookiePermission::ACCESS_LIMIT_THIRD_PARTY:
if (!aIsForeign)
return STATUS_ACCEPTED;
uint32_t priorCookieCount = 0;
nsAutoCString hostFromURI;
aHostURI->GetHost(hostFromURI);
CountCookiesFromHost(hostFromURI, &priorCookieCount);
if (priorCookieCount == 0) {
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI,
aCookieHeader, "third party cookies are blocked "
"for this site");
return STATUS_REJECTED;
}
return STATUS_ACCEPTED;
}
}
}
@ -3263,6 +3279,19 @@ nsCookieService::CheckPrefs(nsIURI *aHostURI,
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "context is third party");
return STATUS_REJECTED;
}
if (mCookieBehavior == BEHAVIOR_LIMITFOREIGN) {
uint32_t priorCookieCount = 0;
nsAutoCString hostFromURI;
aHostURI->GetHost(hostFromURI);
CountCookiesFromHost(hostFromURI, &priorCookieCount);
if (priorCookieCount == 0) {
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "context is third party");
return STATUS_REJECTED;
}
if (mThirdPartySession)
return STATUS_ACCEPT_SESSION;
}
}
// if nothing has complained, accept cookie

View File

@ -325,7 +325,7 @@ class nsCookieService : public nsICookieService
nsRefPtr<DBState> mPrivateDBState;
// cached prefs
uint8_t mCookieBehavior; // BEHAVIOR_{ACCEPT, REJECTFOREIGN, REJECT}
uint8_t mCookieBehavior; // BEHAVIOR_{ACCEPT, REJECTFOREIGN, REJECT, LIMITFOREIGN}
bool mThirdPartySession;
uint16_t mMaxNumberOfCookies;
uint16_t mMaxCookiesPerHost;

View File

@ -31,6 +31,7 @@ interface nsICookiePermission : nsISupports
*/
const nsCookieAccess ACCESS_SESSION = 8;
const nsCookieAccess ACCESS_ALLOW_FIRST_PARTY_ONLY = 9;
const nsCookieAccess ACCESS_LIMIT_THIRD_PARTY = 10;
/**
* setAccess

View File

@ -2,8 +2,12 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
let uri = NetUtil.newURI("http://example.org/");

View File

@ -2,8 +2,19 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
function inChildProcess() {
return Cc["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULRuntime)
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}
function run_test() {
// Allow all cookies if the pref service is available in this process.
if (!inChildProcess())
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
let uri = NetUtil.newURI("http://example.org/");

View File

@ -2,8 +2,19 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
function inChildProcess() {
return Cc["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULRuntime)
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}
function run_test() {
// Allow all cookies if the pref service is available in this process.
if (!inChildProcess())
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
let uri = NetUtil.newURI("http://example.org/");

View File

@ -1,3 +1,9 @@
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
run_test_in_child("../unit/test_parser_0001.js");
}

View File

@ -1,3 +1,9 @@
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
run_test_in_child("../unit/test_parser_0019.js");
}

View File

@ -66,6 +66,10 @@ function setHandler(metadata, response) {
}
function run_test() {
// Allow all cookies if the pref service is available in this process.
if (!inChildProcess())
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
httpserver = new HttpServer();
httpserver.registerPathHandler("/set", setHandler);
httpserver.registerPathHandler("/present", presentHandler);

View File

@ -4,6 +4,7 @@ const Cu = Components.utils;
const Cr = Components.results;
Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://gre/modules/Services.jsm");
var httpserver = new HttpServer();
function setupChannel(suffix)
@ -23,6 +24,9 @@ function checkValueAndTrigger(request, data, ctx)
function run_test()
{
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
httpserver.registerPathHandler("/redirect1", redirectHandler1);
httpserver.registerPathHandler("/redirect2", redirectHandler2);
httpserver.start(4444);

View File

@ -1,3 +1,7 @@
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
function makeURI(str) {
return Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
@ -5,6 +9,8 @@ function makeURI(str) {
}
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
var serv = Components.classes["@mozilla.org/cookieService;1"]
.getService(Components.interfaces.nsICookieService);
var uri = makeURI("http://example.com/");

View File

@ -6,6 +6,13 @@ const Cu = Components.utils;
const Cr = Components.results;
Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://gre/modules/Services.jsm");
function inChildProcess() {
return Cc["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULRuntime)
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}
function check_request_header(chan, name, value) {
var chanValue;
@ -61,6 +68,10 @@ function makeChan() {
var httpserv = null;
function run_test() {
// Allow all cookies if the pref service is available in this process.
if (!inChildProcess())
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
httpserv = new HttpServer();
httpserv.start(4444);

View File

@ -14,11 +14,18 @@ const Cu = Components.utils;
const Cr = Components.results;
Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://gre/modules/Services.jsm");
var httpserver = new HttpServer();
var cookieSetPath = "/setcookie";
var cookieCheckPath = "/checkcookie";
function inChildProcess() {
return Cc["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULRuntime)
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}
// Test array:
// - element 0: name for cookie, used both to set and later to check
// - element 1: loadContext (determines cookie namespace)
@ -109,6 +116,10 @@ function completeCheckCookie(request, data, context) {
function run_test()
{
// Allow all cookies if the pref service is available in this process.
if (!inChildProcess())
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
httpserver.registerPathHandler(cookieSetPath, cookieSetHandler);
httpserver.registerPathHandler(cookieCheckPath, cookieCheckHandler);
httpserver.start(4444);

View File

@ -15,6 +15,9 @@ function makeChan(uri, isPrivate) {
}
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
let publicNotifications = 0;
let privateNotifications = 0;
Services.obs.addObserver(function() {publicNotifications++;}, "cookie-changed", false);

View File

@ -1,3 +1,9 @@
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
run_test_in_child("../unit/test_bug248970_cookie.js");
}

View File

@ -2,6 +2,12 @@
// Run test script in content process instead of chrome (xpcshell's default)
//
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
run_test_in_child("../unit/test_cookie_header.js");
}

View File

@ -1,3 +1,9 @@
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
run_test_in_child("../unit/test_cookiejars.js");
}

View File

@ -7,6 +7,9 @@
// Private resumed request sends times=1 cookie, completes
function run_test() {
// Allow all cookies.
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
do_test_pending();
let httpserv = new HttpServer();

View File

@ -6,7 +6,21 @@
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="text/javascript"><!--
var setAllowAllCookies = false;
function makeXhr(aMethod, aUrl, aRequestBody, aCallback) {
// On the first call, allow all cookies and set cookies, then resume the actual test
if(!setAllowAllCookies)
SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, function () {
setAllowAllCookies = true;
setCookies();
makeXhrCallback(aMethod, aUrl, aRequestBody, aCallback);
});
else
makeXhrCallback(aMethod, aUrl, aRequestBody, aCallback);
}
function makeXhrCallback(aMethod, aUrl, aRequestBody, aCallback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open(aMethod, aUrl, true);
if (aCallback) {
@ -27,10 +41,12 @@
var body = "Hello world! " + (new Array(50)).join("foobaz barr");
makeXhr('post', 'data.json', body, aCallback);
}
document.cookie = "foobar=fooval";
document.cookie = "omgfoo=bug768096";
document.cookie = "badcookie=bug826798=st3fan";
function setCookies() {
document.cookie = "foobar=fooval";
document.cookie = "omgfoo=bug768096";
document.cookie = "badcookie=bug826798=st3fan";
}
// --></script>
</head>
<body>