diff options
Diffstat (limited to 'data/extensions/https-everywhere-eff@eff.org/chrome/content/code/HTTPSRules.js')
-rw-r--r-- | data/extensions/https-everywhere-eff@eff.org/chrome/content/code/HTTPSRules.js | 780 |
1 files changed, 0 insertions, 780 deletions
diff --git a/data/extensions/https-everywhere-eff@eff.org/chrome/content/code/HTTPSRules.js b/data/extensions/https-everywhere-eff@eff.org/chrome/content/code/HTTPSRules.js deleted file mode 100644 index 1ae74d4..0000000 --- a/data/extensions/https-everywhere-eff@eff.org/chrome/content/code/HTTPSRules.js +++ /dev/null @@ -1,780 +0,0 @@ -// Compilation of RegExps is now delayed until they are first used... - -function Rule(from, to) { - this.to = to; - this.from_c = from; // This will become a RegExp after compilation -} - -function Exclusion(pattern) { - this.pattern_c = pattern; // Will become a RegExp after compilation -} - -function CookieRule(host, cookiename) { - this.host = host; - this.name = cookiename; - - // These will be made during compilation: - - //this.host_c = new RegExp(host); - //this.name_c = new RegExp(cookiename); -} - -function RuleSet(id, name, xmlName, match_rule, default_off, platform) { - if(xmlName == "WordPress.xml" || xmlName == "Github.xml") { - this.log(NOTE, "RuleSet( name="+name+", xmlName="+xmlName+", match_rule="+match_rule+", default_off="+default_off+", platform="+platform+" )"); - } - - this.id=id; - this.on_by_default = true; - this.compiled = false; - this.name = name; - this.xmlName = xmlName; - this.notes = ""; - - if (match_rule) this.ruleset_match_c = new RegExp(match_rule); - else this.ruleset_match_c = null; - if (default_off) { - // Perhaps problematically, this currently ignores the actual content of - // the default_off XML attribute. Ideally we'd like this attribute to be - // "valueless" - this.notes = default_off; - this.on_by_default = false; - } - if (platform) - if (platform.search(HTTPSRules.localPlatformRegexp) == -1) { - this.on_by_default = false; - this.notes = "Only for " + platform; - } - - this.rules = []; - this.exclusions = []; - this.cookierules = []; - - this.rule_toggle_prefs = HTTPSEverywhere.instance.rule_toggle_prefs; - - try { - // if this pref exists, use it - this.active = this.rule_toggle_prefs.getBoolPref(name); - } catch(e) { - // if not, use the default - this.active = this.on_by_default; - } -} - -var dom_parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser); - -RuleSet.prototype = { - - ensureCompiled: function() { - // Postpone compilation of exclusions, rules and cookies until now, to accelerate - // browser load time. - if (this.compiled) return; - var i; - - for (i = 0; i < this.exclusions.length; ++i) { - this.exclusions[i].pattern_c = new RegExp(this.exclusions[i].pattern_c); - } - for (i = 0; i < this.rules.length; ++i) { - this.rules[i].from_c = new RegExp(this.rules[i].from_c); - } - - for (i = 0; i < this.cookierules.length; i++) { - var cr = this.cookierules[i]; - cr.host_c = new RegExp(cr.host); - cr.name_c = new RegExp(cr.name); - } - - this.compiled = true; - }, - - apply: function(urispec) { - // return null if it does not apply - // and the new url if it does apply - var i; - var returl = null; - this.ensureCompiled(); - // If a rulset has a match_rule and it fails, go no further - if (this.ruleset_match_c && !this.ruleset_match_c.test(urispec)) { - this.log(VERB, "ruleset_match_c excluded " + urispec); - return null; - } - // Even so, if we're covered by an exclusion, go home - for (i = 0; i < this.exclusions.length; ++i) { - if (this.exclusions[i].pattern_c.test(urispec)) { - this.log(DBUG,"excluded uri " + urispec); - return null; - } - } - // Okay, now find the first rule that triggers - for (i = 0; i < this.rules.length; ++i) { - // This is just for displaying inactive rules - returl = urispec.replace(this.rules[i].from_c, this.rules[i].to); - if (returl != urispec) { - // we rewrote the uri - this.log(DBUG, "Rewrote " + urispec + " -> " + returl + " using " + this.xmlName + ": " + this.rules[i].from_c + " -> " + this.rules[i].to); - return returl; - } - } - - return null; - }, - log: function(level, msg) { - https_everywhereLog(level, msg); - }, - - wouldMatch: function(hypothetical_uri, alist) { - // return true if this ruleset would match the uri, assuming it were http - // used for judging moot / inactive rulesets - // alist is optional - - // if the ruleset is already somewhere in this applicable list, we don't - // care about hypothetical wouldMatch questions - if (alist && (this.name in alist.all)) return false; - - this.log(DBUG,"Would " +this.name + " match " +hypothetical_uri.spec + - "? serial " + (alist && alist.serial)); - - var uri = hypothetical_uri.clone(); - if (uri.scheme == "https") uri.scheme = "http"; - var urispec = uri.spec; - - this.ensureCompiled(); - - if (this.ruleset_match_c && !this.ruleset_match_c.test(urispec)) - return false; - - for (var i = 0; i < this.exclusions.length; ++i) - if (this.exclusions[i].pattern_c.test(urispec)) return false; - - for (var i = 0; i < this.rules.length; ++i) - if (this.rules[i].from_c.test(urispec)) return true; - return false; - }, - - transformURI: function(uri) { - // If no rule applies, return null; if a rule would have applied but was - // inactive, return 0; otherwise, return a fresh uri instance - // for the target - var newurl = this.apply(uri.spec); - if (null == newurl) - return null; - var newuri = Components.classes["@mozilla.org/network/standard-url;1"]. - createInstance(CI.nsIStandardURL); - newuri.init(CI.nsIStandardURL.URLTYPE_STANDARD, 443, - newurl, uri.originCharset, null); - newuri = newuri.QueryInterface(CI.nsIURI); - return newuri; - }, - - enable: function() { - // Enable us. - this.rule_toggle_prefs.setBoolPref(this.name, true); - this.active = true; - }, - - disable: function() { - // Disable us. - this.rule_toggle_prefs.setBoolPref(this.name, false); - this.active = false; - }, - - toggle: function() { - this.active = !this.active; - this.rule_toggle_prefs.setBoolPref(this.name, this.active); - }, - - clear: function() { - try { - this.rule_toggle_prefs.clearUserPref(this.name); - } catch(e) { - // this ruleset has never been toggled - } - this.active = this.on_by_default; - } -}; - -const RuleWriter = { - - getCustomRuleDir: function() { - var loc = "ProfD"; // profile directory - var file = - CC["@mozilla.org/file/directory_service;1"] - .getService(CI.nsIProperties) - .get(loc, CI.nsILocalFile) - .clone(); - file.append("HTTPSEverywhereUserRules"); - // Check for existence, if not, create. - if (!file.exists()) { - file.create(CI.nsIFile.DIRECTORY_TYPE, 0700); - } - if (!file.isDirectory()) { - // XXX: Arg, death! - } - return file; - }, - - chromeToPath: function (aPath) { - if (!aPath || !(/^chrome:/.test(aPath))) - return; //not a chrome url - - var ios = - CC['@mozilla.org/network/io-service;1'] - .getService(CI.nsIIOService); - var uri = ios.newURI(aPath, "UTF-8", null); - var cr = - CC['@mozilla.org/chrome/chrome-registry;1'] - .getService(CI.nsIChromeRegistry); - var rv = cr.convertChromeURL(uri).spec; - - if (/^file:/.test(rv)) - rv = this.urlToPath(rv); - else - rv = this.urlToPath("file://"+rv); - - return rv; - }, - - urlToPath: function (aPath) { - if (!aPath || !/^file:/.test(aPath)) - return ; - - var ph = - CC["@mozilla.org/network/protocol;1?name=file"] - .createInstance(CI.nsIFileProtocolHandler); - var rv = ph.getFileFromURLSpec(aPath).path; - - return rv; - }, - - readFromUrl: function (url) { - var ios = CC['@mozilla.org/network/io-service;1'] - .getService(CI.nsIIOService); - var encoding = "UTF-8"; - var channel = ios.newChannel(url, encoding, null); - var stream = channel.open(); - var streamSize = stream.available(); - - if (!streamSize) { - return null; - } - - var convStream = CC["@mozilla.org/intl/converter-input-stream;1"] - .createInstance(CI.nsIConverterInputStream); - - convStream.init(stream, encoding, streamSize, - convStream.DEFAULT_REPLACEMENT_CHARACTER); - - var data = {}; - convStream.readString(streamSize, data); - - return data.value; - }, - - readFromFile: function(file) { - if (!file.exists()) - return null; - var data = ""; - var fstream = CC["@mozilla.org/network/file-input-stream;1"] - .createInstance(CI.nsIFileInputStream); - var sstream = CC["@mozilla.org/scriptableinputstream;1"] - .createInstance(CI.nsIScriptableInputStream); - fstream.init(file, -1, 0, 0); - sstream.init(fstream); - - var str = sstream.read(4096); - while (str.length > 0) { - data += str; - str = sstream.read(4096); - } - - sstream.close(); - fstream.close(); - return data; - }, - - write: function(file, data) { - //if (!file.exists()) - // return null; - this.log(DBUG, "Opening " + file.path + " for writing"); - var fstream = CC["@mozilla.org/network/file-output-stream;1"] - .createInstance(CI.nsIFileOutputStream); - fstream.init(file, -1, -1, 0); - - var retval = fstream.write(data, data.length); - this.log(DBUG, "Got retval " + retval); - fstream.close(); - return data; - }, - - rulesetFromFile: function(file, rule_store, ruleset_id) { - if ((rule_store.targets == null) && (rule_store.targets != {})) - this.log(WARN, "TARGETS IS NULL"); - var data = this.readFromFile(file); - if (!data) return null; - return this.readFromString(data, rule_store, ruleset_id); - }, - - readFromString: function(data, rule_store, ruleset_id) { - try { - var xmlruleset = dom_parser.parseFromString(data, "text/xml"); - } catch(e) { // file has been corrupted; XXX: handle error differently - this.log(WARN,"Error in XML data: " + e + "\n" + data); - return null; - } - this.parseOneRuleset(xmlruleset.documentElement, rule_store, ruleset_id); - }, - - parseOneRuleset: function(xmlruleset, rule_store, ruleset_id) { - // Extract an xmlruleset into the rulestore - if (!xmlruleset.getAttribute("name")) { - this.log(WARN, "This blob: '" + xmlruleset + "' is not a ruleset\n"); - return null; - } - - this.log(DBUG, "Parsing " + xmlruleset.getAttribute("name")); - - var match_rl = xmlruleset.getAttribute("match_rule"); - var dflt_off = xmlruleset.getAttribute("default_off"); - var platform = xmlruleset.getAttribute("platform"); - var rs = new RuleSet(ruleset_id, xmlruleset.getAttribute("name"), xmlruleset.getAttribute("f"), match_rl, dflt_off, platform); - - // see if this ruleset has the same name as an existing ruleset; - // if so, this ruleset is ignored; DON'T add or return it. - if (rs.name in rule_store.rulesetsByName) { - this.log(WARN, "Error: found duplicate rule name " + rs.name); - return null; - } - - // Add this ruleset id into HTTPSRules.targets if it's not already there. - // This should only happen for custom user rules. Built-in rules get - // their ids preloaded into the targets map, and have their <target> - // tags stripped when the JSON database is built. - var targets = xmlruleset.getElementsByTagName("target"); - for (var i = 0; i < targets.length; i++) { - var host = targets[i].getAttribute("host"); - if (!host) { - this.log(WARN, "<target> missing host in " + xmlruleset.getAttribute("name")); - return null; - } - if (! rule_store.targets[host]) - rule_store.targets[host] = []; - this.log(DBUG, "Adding " + host + " to targets, pointing at " + ruleset_id); - rule_store.targets[host].push(ruleset_id); - } - - var exclusions = xmlruleset.getElementsByTagName("exclusion"); - for (var i = 0; i < exclusions.length; i++) { - var exclusion = new Exclusion(exclusions[i].getAttribute("pattern")); - rs.exclusions.push(exclusion); - } - - var rules = xmlruleset.getElementsByTagName("rule"); - for (var i = 0; i < rules.length; i++) { - var rule = new Rule(rules[i].getAttribute("from"), - rules[i].getAttribute("to")); - rs.rules.push(rule); - } - - var securecookies = xmlruleset.getElementsByTagName("securecookie"); - for (var i = 0; i < securecookies.length; i++) { - var c_rule = new CookieRule(securecookies[i].getAttribute("host"), - securecookies[i].getAttribute("name")); - rs.cookierules.push(c_rule); - this.log(DBUG,"Cookie rule "+ c_rule.host+ " " +c_rule.name); - } - - rule_store.rulesets.push(rs); - rule_store.rulesetsByID[rs.id] = rs; - rule_store.rulesetsByName[rs.name] = rs; - }, - - enumerate: function(dir) { - // file is the given directory (nsIFile) - var entries = dir.directoryEntries; - var ret = []; - while(entries.hasMoreElements()) { - var entry = entries.getNext(); - entry.QueryInterface(Components.interfaces.nsIFile); - ret.push(entry); - } - return ret; - }, -}; - - - -const HTTPSRules = { - init: function() { - try { - this.rulesets = []; - this.targets = {}; // dict mapping target host pattern -> list of - // applicable ruleset ids - this.rulesetsByID = {}; - this.rulesetsByName = {}; - var t1 = new Date().getTime(); - this.checkMixedContentHandling(); - var rulefiles = RuleWriter.enumerate(RuleWriter.getCustomRuleDir()); - - this.loadTargets(); - this.scanRulefiles(rulefiles); - - } catch(e) { - this.log(DBUG,"Rules Failed: "+e); - } - var t2 = new Date().getTime(); - this.log(NOTE,"Loading targets took " + (t2 - t1) / 1000.0 + " seconds"); - - return; - }, - - /** - * Read and parse the ruleset JSON. - * Note: This only parses the outer JSON wrapper. Each ruleset is itself an - * XML string, which will be parsed on an as-needed basis. - */ - loadTargets: function() { - var loc = "chrome://https-everywhere/content/rulesets.json"; - var data = RuleWriter.readFromUrl(loc); - var rules = JSON.parse(data); - this.targets = rules.targets; - this.rulesetStrings = rules.rulesetStrings; - }, - - checkMixedContentHandling: function() { - // Firefox 23+ blocks mixed content by default, so rulesets that create - // mixed content situations should be disabled there - var appInfo = CC["@mozilla.org/xre/app-info;1"].getService(CI.nsIXULAppInfo); - var platformVer = appInfo.platformVersion; - var versionChecker = CC["@mozilla.org/xpcom/version-comparator;1"] - .getService(CI.nsIVersionComparator); - var prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefService).getBranch(""); - - - // If mixed content is present and enabled, and the user hasn't opted to enable - // mixed content triggering rules, leave them out. Otherwise add them in. - if(versionChecker.compare(appInfo.version, "23.0a1") >= 0 - && prefs.getBoolPref("security.mixed_content.block_active_content") - && !prefs.getBoolPref("extensions.https_everywhere.enable_mixed_rulesets")) { - this.log(INFO, "Not activating rules that trigger mixed content errors."); - this.localPlatformRegexp = new RegExp("firefox"); - } else { - this.log(INFO, "Activating rules that would normally trigger mixed content"); - this.localPlatformRegexp = new RegExp("(firefox|mixedcontent)"); - } - }, - - scanRulefiles: function(rulefiles) { - var i = 0; - var r = null; - for(i = 0; i < rulefiles.length; ++i) { - try { - this.log(DBUG,"Loading ruleset file: "+rulefiles[i].path); - var ruleset_id = "custom_" + i; - RuleWriter.rulesetFromFile(rulefiles[i], this, ruleset_id); - } catch(e) { - this.log(WARN, "Error in ruleset file: " + e); - if (e.lineNumber) - this.log(WARN, "(line number: " + e.lineNumber + ")"); - } - } - }, - - resetRulesetsToDefaults: function() { - // Callable from within the prefs UI and also for cleaning up buggy - // configurations... - for (var i in this.rulesets) { - this.rulesets[i].clear(); - } - }, - - - rewrittenURI: function(alist, input_uri) { - // This function oversees the task of working out if a uri should be - // rewritten, what it should be rewritten to, and recordkeeping of which - // applicable rulesets are and aren't active. Previously this returned - // the new uri if there was a rewrite. Now it returns a JS object with a - // newuri attribute and an applied_ruleset attribute (or null if there's - // no rewrite). - var i = 0; - userpass_present = false; // Global so that sanitiseURI can tweak it. - // Why does JS have no tuples, again? - var blob = {}; blob.newuri = null; - if (!alist) this.log(DBUG, "No applicable list rewriting " + input_uri.spec); - this.log(DBUG, "Processing " + input_uri.spec); - - var uri = this.sanitiseURI(input_uri); - - // Get the list of rulesets that target this host - try { - var rs = this.potentiallyApplicableRulesets(uri.host); - } catch(e) { - this.log(NOTE, 'Could not check applicable rules for '+uri.spec + '\n'+e); - return null; - } - - // ponder each potentially applicable ruleset, working out if it applies - // and recording it as active/inactive/moot/breaking in the applicable list - for (i = 0; i < rs.length; ++i) { - if (!rs[i].active) { - if (alist && rs[i].wouldMatch(uri, alist)) - alist.inactive_rule(rs[i]); - continue; - } - blob.newuri = rs[i].transformURI(uri); - if (blob.newuri) { - if (alist) { - if (uri.spec in https_everywhere_blacklist) - alist.breaking_rule(rs[i]); - else - alist.active_rule(rs[i]); - } - if (userpass_present) blob.newuri.userPass = input_uri.userPass; - blob.applied_ruleset = rs[i]; - return blob; - } - if (uri.scheme == "https" && alist) { - // we didn't rewrite but the rule applies to this domain and the - // requests are going over https - if (rs[i].wouldMatch(uri, alist)) alist.moot_rule(rs[i]); - continue; - } - } - return null; - }, - - sanitiseURI: function(input_uri) { - // Rulesets shouldn't try to parse usernames and passwords. If we find - // those, apply the ruleset without them (and then add them back later). - // When .userPass is absent, sometimes it is false and sometimes trying - // to read it raises an exception (probably depending on the URI type). - var uri = input_uri; - try { - if (input_uri.userPass) { - uri = input_uri.clone(); - userpass_present = true; // tweaking a global in our caller :( - uri.userPass = null; - } - } catch(e) {} - - // example.com. is equivalent to example.com - // example.com.. is invalid, but firefox would load it anyway - try { - if (uri.host) - try { - var h = uri.host; - if (h.charAt(h.length - 1) == ".") { - while (h.charAt(h.length - 1) == ".") - h = h.slice(0,-1); - uri = uri.clone(); - uri.host = h; - } - } catch(e) { - this.log(WARN, "Failed to normalise domain: "); - try {this.log(WARN, input_uri.host);} - catch(e2) {this.log(WARN, "bang" + e + " & " + e2 + " & "+ input_uri);} - } - } catch(e3) { - this.log(INFO, "uri.host is explosive!"); - try { this.log(INFO, "(" + uri.spec + ")"); } // happens for about: uris and so forth - catch(e4) { this.log(WARN, "(and unprintable!!!!!!)"); } - } - return uri; - }, - - setInsert: function(intoList, fromList) { - // Insert any elements from fromList into intoList, if they are not - // already there. fromList may be null. - if (!fromList) return; - for (var i = 0; i < fromList.length; i++) - if (intoList.indexOf(fromList[i]) == -1) - intoList.push(fromList[i]); - }, - - // Load a ruleset by numeric id, e.g. 234 - loadRulesetById: function(ruleset_id) { - RuleWriter.readFromString(this.rulesetStrings[ruleset_id], this, ruleset_id); - }, - - // Get all rulesets matching a given target, lazy-loading from DB as necessary. - rulesetsByTarget: function(target) { - var rulesetIds = this.targets[target]; - - var output = []; - if (rulesetIds) { - this.log(INFO, "For target " + target + ", found ids " + rulesetIds.toString()); - for (var i = 0; i < rulesetIds.length; i++) { - var id = rulesetIds[i]; - if (!this.rulesetsByID[id]) { - this.loadRulesetById(id); - } - if (this.rulesetsByID[id]) { - output.push(this.rulesetsByID[id]); - } - } - } else { - this.log(DBUG, "For target " + target + ", found no ids in DB"); - } - return output; - }, - - /** - * Return a list of rulesets that declare targets matching a given hostname. - * The returned rulesets include those that are disabled for various reasons. - * This function is only defined for fully-qualified hostnames. Wildcards and - * cookie-style domain attributes with a leading dot are not permitted. - * @param host {string} - * @return {Array.<RuleSet>} - */ - potentiallyApplicableRulesets: function(host) { - var i, tmp, t; - var results = []; - - var attempt = function(target) { - this.setInsert(results, this.rulesetsByTarget(target)); - }.bind(this); - - attempt(host); - - // Ensure host is well-formed (RFC 1035) - if (host.indexOf("..") != -1 || host.length > 255) { - this.log(WARN,"Malformed host passed to potentiallyApplicableRulesets: " + host); - return null; - } - - // replace each portion of the domain with a * in turn - var segmented = host.split("."); - for (i = 0; i < segmented.length; ++i) { - tmp = segmented[i]; - segmented[i] = "*"; - t = segmented.join("."); - segmented[i] = tmp; - attempt(t); - } - // now eat away from the left, with *, so that for x.y.z.google.com we - // check *.z.google.com and *.google.com (we did *.y.z.google.com above) - for (i = 2; i <= segmented.length - 2; ++i) { - t = "*." + segmented.slice(i,segmented.length).join("."); - attempt(t); - } - this.log(DBUG,"Potentially applicable rules for " + host + ":"); - for (i = 0; i < results.length; ++i) - this.log(DBUG, " " + results[i].name); - return results; - }, - - /** - * If a cookie's domain attribute has a leading dot to indicate it should be - * sent for all subdomains (".example.com"), return the actual host part (the - * part after the dot). - * - * @param cookieDomain {string} A cookie domain to strip a leading dot from. - * @return {string} a fully qualified hostname. - */ - hostFromCookieDomain: function(cookieDomain) { - if (cookieDomain.length > 0 && cookieDomain[0] == ".") { - return cookieDomain.slice(1); - } else { - return cookieDomain; - } - }, - - /** - * Check to see if the Cookie object c meets any of our cookierule criteria - * for being marked as secure. - * - * @param applicable_list {ApplicableList} an ApplicableList for record keeping - * @param c {nsICookie2} The cookie we might secure. - * @param known_https {boolean} True if the cookie appeared in an HTTPS request and - * so we know it is okay to mark it secure (assuming a cookierule matches it. - * TODO(jsha): Double-check that the code calling this actually does that. - * @return {boolean} True if the cookie in question should have the 'secure' - * flag set to true. - */ - shouldSecureCookie: function(applicable_list, c, known_https) { - this.log(DBUG," rawhost: " + c.rawHost + " name: " + c.name + " host" + c.host); - var i,j; - // potentiallyApplicableRulesets is defined on hostnames not cookie-style - // "domain" attributes, so we strip a leading dot before calling. - var rs = this.potentiallyApplicableRulesets(this.hostFromCookieDomain(c.host)); - for (i = 0; i < rs.length; ++i) { - var ruleset = rs[i]; - if (ruleset.active) { - ruleset.ensureCompiled(); - // Never secure a cookie if this page might be HTTP - if (!(known_https || this.safeToSecureCookie(c.rawHost))) { - continue; - } - for (j = 0; j < ruleset.cookierules.length; j++) { - var cr = ruleset.cookierules[j]; - if (cr.host_c.test(c.host) && cr.name_c.test(c.name)) { - if (applicable_list) applicable_list.active_rule(ruleset); - this.log(INFO,"Active cookie rule " + ruleset.name); - return true; - } - } - if (ruleset.cookierules.length > 0 && applicable_list) { - applicable_list.moot_rule(ruleset); - } - } else if (ruleset.cookierules.length > 0) { - if (applicable_list) { - applicable_list.inactive_rule(ruleset); - } - this.log(INFO,"Inactive cookie rule " + ruleset.name); - } - } - return false; - }, - - /** - * Check if the domain might be being served over HTTP. If so, it isn't - * safe to secure a cookie! We can't always know this for sure because - * observing cookie-changed doesn't give us enough context to know the - * full origin URI. In particular, if cookies are set from Javascript (as - * opposed to HTTP/HTTPS responses), we don't know what page context that - * Javascript ran in. - - * First, if there are any redirect loops on this domain, don't secure - * cookies. XXX This is not a very satisfactory heuristic. Sometimes we - * would want to secure the cookie anyway, because the URLs that loop are - * not authenticated or not important. Also by the time the loop has been - * observed and the domain blacklisted, a cookie might already have been - * flagged as secure. - * - * @param domain {string} The cookie's 'domain' attribute. - * @return {boolean} True if it's safe to secure a cookie on that domain. - */ - safeToSecureCookie: function(domain) { - if (domain in https_blacklist_domains) { - this.log(INFO, "cookies for " + domain + "blacklisted"); - return false; - } - - // If we passed that test, make up a random URL on the domain, and see if - // we would HTTPSify that. - try { - var nonce_path = "/" + Math.random().toString(); - nonce_path = nonce_path + nonce_path; - var test_uri = "http://" + domain + nonce_path; - } catch (e) { - this.log(WARN, "explosion in safeToSecureCookie for " + domain + "\n" - + "(" + e + ")"); - return false; - } - - this.log(DBUG, "Testing securecookie applicability with " + test_uri); - // potentiallyApplicableRulesets is defined on hostnames not cookie-style - // "domain" attributes, so we strip a leading dot before calling. - var rs = this.potentiallyApplicableRulesets(this.hostFromCookieDomain(domain)); - for (var i = 0; i < rs.length; ++i) { - if (!rs[i].active) continue; - var rewrite = rs[i].apply(test_uri); - if (rewrite) { - this.log(DBUG, "Safe to secure cookie for " + test_uri + ": " + rewrite); - return true; - } - } - this.log(DBUG, "Unsafe to secure cookie for " + test_uri); - return false; - } -}; |