Skip to content

Commit edc10d0

Browse files
committed
First attempt to not secure cookies on HTTP origins
https://trac.torproject.org/projects/tor/ticket/7491
1 parent d4abf89 commit edc10d0

File tree

3 files changed

+51
-8
lines changed

3 files changed

+51
-8
lines changed

src/chrome/content/code/HTTPS.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ const HTTPS = {
5050
https_everywhere_blacklist[channel.URI.spec] = true;
5151
}
5252
https_everywhere_blacklist[channel.URI.spec] = blob.applied_ruleset;
53+
var domain = null;
54+
try { domain = channel.URI.host; } catch (e) {}
55+
if (domain) https_blacklist_domains[domain] = true;
5356
return false;
5457
}
5558

@@ -224,7 +227,7 @@ const HTTPS = {
224227
for each (var cs in cookies.split("\n")) {
225228
this.log(DBUG, "Examining cookie: ");
226229
c = new Cookie(cs, host);
227-
if (!c.secure && HTTPSRules.shouldSecureCookie(alist, c)) {
230+
if (!c.secure && HTTPSRules.shouldSecureCookie(alist, c, true)) {
228231
this.log(INFO, "Securing cookie: " + c.domain + " " + c.name);
229232
c.secure = true;
230233
req.setResponseHeader("Set-Cookie", c.source + ";Secure", true);
@@ -235,7 +238,7 @@ const HTTPS = {
235238
},
236239

237240
handleInsecureCookie: function(c) {
238-
if (HTTPSRules.shouldSecureCookie(null, c)) {
241+
if (HTTPSRules.shouldSecureCookie(null, c, false)) {
239242
this.log(INFO, "Securing cookie from event: " + c.domain + " " + c.name);
240243
var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
241244
.getService(Components.interfaces.nsICookieManager2);

src/chrome/content/code/HTTPSRules.js

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@ RuleSet.prototype = {
9292
wouldMatch: function(hypothetical_uri, alist) {
9393
// return true if this ruleset would match the uri, assuming it were http
9494
// used for judging moot / inactive rulesets
95+
// alist is optional
9596

9697
// if the ruleset is already somewhere in this applicable list, we don't
97-
// care about hypothetical wouldMatch questios
98-
if (this.name in alist.all) return false;
98+
// care about hypothetical wouldMatch questions
99+
if (alist && (this.name in alist.all)) return false;
99100

100101
this.log(DBUG,"Would " +this.name + " match " +hypothetical_uri.spec +
101-
"? serial " + alist.serial);
102+
"? serial " + (alist && alist.serial));
102103

103104
var uri = hypothetical_uri.clone();
104105
if (uri.scheme == "https") uri.scheme = "http";
@@ -544,19 +545,25 @@ const HTTPSRules = {
544545
return results;
545546
},
546547

547-
shouldSecureCookie: function(applicable_list, c) {
548+
shouldSecureCookie: function(applicable_list, c, known_https) {
548549
// Check to see if the Cookie object c meets any of our cookierule citeria
549-
// for being marked as secure
550+
// for being marked as secure.
551+
// @applicable_list : an ApplicableList or record keeping
552+
// @c : an nsICookie2
553+
// @known_https : true if we know the page setting the cookie is https
550554
//this.log(DBUG, "Testing cookie:");
551555
//this.log(DBUG, " name: " + c.name);
552556
//this.log(DBUG, " host: " + c.host);
553557
//this.log(DBUG, " domain: " + c.domain);
554-
//this.log(DBUG, " rawhost: " + c.rawHost);
558+
this.log(DBUG, " rawhost: " + c.rawHost);
555559
var i,j;
556560
var rs = this.potentiallyApplicableRulesets(c.host);
557561
for (i = 0; i < rs.length; ++i) {
558562
var ruleset = rs[i];
559563
if (ruleset.active) {
564+
// Never secure a cookie if this page might be HTTP
565+
if (!known_https && !this.safeToSecureCookie(c.rawhost))
566+
continue;
560567
for (j = 0; j < ruleset.cookierules.length; j++) {
561568
var cr = ruleset.cookierules[j];
562569
if (cr.host_c.test(c.host) && cr.name_c.test(c.name)) {
@@ -573,6 +580,36 @@ const HTTPSRules = {
573580
}
574581
}
575582
return false;
583+
},
584+
585+
safeToSecureCookie(domain) {
586+
// Check if the domain might be being served over HTTP. If so, it isn't
587+
// safe to secure a cookie! We can't always know this for sure because
588+
// observing cookie-changed doesn't give us enough context to know the
589+
// full origin URI.
590+
591+
// If there are any redirect loops on this domain, don't secure cookies.
592+
// XXX This is not a very satisfactory heuristic. Sometimes we would want
593+
// to secure the cookie anyway, because the URLs that loop are not
594+
// authenticated or not important. Also by the time
595+
596+
if (domain in https_blacklist_domains) return false;
597+
598+
// If we passed that test, make up a random URL on the domain, and see if
599+
// we would HTTPSify that.
600+
601+
var ios = CC['@mozilla.org/network/io-service;1']
602+
.getService(CI.nsIIOService);
603+
try {
604+
var nonce_path = Math.random().toString() + "/" + Math.random().toString();
605+
var test_uri = ios.newURI("http://" + nonce_path, "UTF-8", null);
606+
} catch (e) {
607+
this.log(WARN, "explosion in safeToSecureCookie for " + domain + "\n"
608+
+ "(" + e + ")");
609+
return false;
610+
}
611+
return wouldMatch(test_uri, null);
576612
}
577613

614+
578615
};

src/components/https-everywhere.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ https_domains = {}; // maps domain patterns (with at most one
1414
https_everywhere_blacklist = {}; // URLs we've given up on rewriting because
1515
// of redirection loops
1616

17+
https_blacklist_domains = {}; // domains for which there is at least one
18+
// blacklisted URL
19+
1720
//
1821
const CI = Components.interfaces;
1922
const CC = Components.classes;

0 commit comments

Comments
 (0)