Skip to content

Commit 6c11705

Browse files
committed
Fix cookie securing code for async.
1 parent 2d431ec commit 6c11705

1 file changed

Lines changed: 50 additions & 31 deletions

File tree

src/chrome/content/code/HTTPSRules.js

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -400,23 +400,7 @@ const HTTPSRules = {
400400
var dbFile = new FileUtils.File(RuleWriter.chromeToPath("chrome://https-everywhere/content/rulesets.sqlite"));
401401
this.rulesetDBConn = Services.storage.openDatabase(dbFile);
402402

403-
// Preload the mapping of hostname target -> ruleset ID from DB.
404-
// This is a little slow (287 ms on a Core2 Duo @ 2.2GHz with SSD),
405-
// but is faster than loading all of the rulesets. If this becomes a
406-
// bottleneck, change it to load in a background webworker, or load
407-
// a smaller bloom filter instead.
408-
var targetsQuery = this.rulesetDBConn.createStatement("select host, ruleset_id from targets");
409-
this.log(DBUG, "Loading targets...");
410-
while (targetsQuery.executeStep()) {
411-
var host = targetsQuery.row.host;
412-
var id = targetsQuery.row.ruleset_id;
413-
if (!this.targets[host]) {
414-
this.targets[host] = [id];
415-
} else {
416-
this.targets[host].push(id);
417-
}
418-
}
419-
this.log(DBUG, "Loading adding targets.");
403+
this.loadTargets();
420404
} catch(e) {
421405
this.log(DBUG,"Rules Failed: "+e);
422406
}
@@ -426,6 +410,25 @@ const HTTPSRules = {
426410
return;
427411
},
428412

413+
loadTargets: function() {
414+
// Preload the mapping of hostname target -> ruleset ID from DB.
415+
// This is a little slow (287 ms on a Core2 Duo @ 2.2GHz with SSD),
416+
// but is faster than loading all of the rulesets. If this becomes a
417+
// bottleneck, change it to load in a background webworker, or load
418+
// a smaller bloom filter instead.
419+
var targetsQuery = this.rulesetDBConn.createStatement("select host, ruleset_id from targets");
420+
this.log(DBUG, "Loading targets...");
421+
while (targetsQuery.executeStep()) {
422+
var host = targetsQuery.row.host;
423+
var id = targetsQuery.row.ruleset_id;
424+
if (!this.targets[host]) {
425+
this.targets[host] = [id];
426+
} else {
427+
this.targets[host].push(id);
428+
}
429+
}
430+
},
431+
429432
checkMixedContentHandling: function() {
430433
// Firefox 23+ blocks mixed content by default, so rulesets that create
431434
// mixed content situations should be disabled there
@@ -518,11 +521,12 @@ const HTTPSRules = {
518521
blob.newuri = rs[i].transformURI(uri);
519522
if (blob.newuri) {
520523
if (alist) {
521-
if (uri.spec in https_everywhere_blacklist)
524+
if (uri.spec in https_everywhere_blacklist) {
522525
alist.breaking_rule(rs[i]);
523-
else
526+
} else {
524527
alist.active_rule(rs[i]);
525-
}
528+
}
529+
}
526530
if (userpass_present) blob.newuri.userPass = input_uri.userPass;
527531
blob.applied_ruleset = rs[i];
528532
callback(blob);
@@ -533,7 +537,7 @@ const HTTPSRules = {
533537
// requests are going over https
534538
if (rs[i].wouldMatch(uri, alist)) alist.moot_rule(rs[i]);
535539
continue;
536-
}
540+
}
537541
}
538542
callback(null);
539543
return;
@@ -736,15 +740,33 @@ const HTTPSRules = {
736740
var i,j;
737741
// potentiallyApplicableRulesets is defined on hostnames not cookie-style
738742
// "domain" attributes, so we strip a leading dot before calling.
739-
// XXX FIX FOR ASYNC
740-
return;
741-
var rs = this.potentiallyApplicableRulesets(this.hostFromCookieDomain(c.host));
743+
var host = this.hostFromCookieDomain(c.host);
744+
745+
// When checking for potentially applicable rulesets, we have to wait for a
746+
// callback, because we may need to load the rulesets from disk. However, in
747+
// practice this callback will always be run immediately, because the
748+
// ruleset for the necessary host will have been loaded already for the HTTP
749+
// request.
750+
var result;
751+
var callbackedImmediate = this.potentiallyApplicableRulesets(host, function() {
752+
result = this.shouldSecureCookieWithRulesets(applicable_list, c, known_https, rs);
753+
});
754+
if (callbackedImmediate) {
755+
return result;
756+
} else {
757+
this.log(WARN, "Shouldn't happen: rulesets were not already loaded for host " + host)
758+
// Default to securing cookies if we aren't sure.
759+
return true
760+
}
761+
},
762+
763+
shouldSecureCookieWithRulesets: function(applicable_list, c, known_https, rs) {
742764
for (i = 0; i < rs.length; ++i) {
743765
var ruleset = rs[i];
744766
if (ruleset.active) {
745767
ruleset.ensureCompiled();
746768
// Never secure a cookie if this page might be HTTP
747-
if (!(known_https || this.safeToSecureCookie(c.rawHost))) {
769+
if (!(known_https || this.safeToSecureCookie(c.rawHost, rs))) {
748770
continue;
749771
}
750772
for (j = 0; j < ruleset.cookierules.length; j++) {
@@ -784,9 +806,10 @@ const HTTPSRules = {
784806
* flagged as secure.
785807
*
786808
* @param domain {string} The cookie's 'domain' attribute.
809+
* @param rs {Array.<Ruleset>} A list of potentially applicable rulesets.
787810
* @return {boolean} True if it's safe to secure a cookie on that domain.
788811
*/
789-
safeToSecureCookie: function(domain) {
812+
safeToSecureCookie: function(domain, rs) {
790813
if (domain in https_blacklist_domains) {
791814
this.log(INFO, "cookies for " + domain + "blacklisted");
792815
return false;
@@ -805,11 +828,7 @@ const HTTPSRules = {
805828
}
806829

807830
this.log(DBUG, "Testing securecookie applicability with " + test_uri);
808-
// potentiallyApplicableRulesets is defined on hostnames not cookie-style
809-
// "domain" attributes, so we strip a leading dot before calling.
810-
// XXX FIX FOR ASYNC
811-
return
812-
var rs = this.potentiallyApplicableRulesets(this.hostFromCookieDomain(domain));
831+
813832
for (var i = 0; i < rs.length; ++i) {
814833
if (!rs[i].active) continue;
815834
var rewrite = rs[i].apply(test_uri);

0 commit comments

Comments
 (0)