Advertisement
Guest User

HTTPS Everywhere 2013.8.16 loop fix

a guest
Aug 17th, 2013
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.35 KB | None | 0 0
  1. function Rule(from, to) {
  2. //this.from = from;
  3. this.to = to;
  4. this.from_c = new RegExp(from);
  5. }
  6.  
  7. function Exclusion(pattern) {
  8. //this.pattern = pattern;
  9. this.pattern_c = new RegExp(pattern);
  10. }
  11.  
  12. function CookieRule(host, cookiename) {
  13. this.host = host
  14. this.host_c = new RegExp(host);
  15. this.name = cookiename;
  16. this.name_c = new RegExp(cookiename);
  17. }
  18.  
  19. function RuleSet(set_name, match_rule, default_state, note) {
  20. this.name = set_name;
  21. if (match_rule)
  22. this.ruleset_match_c = new RegExp(match_rule);
  23. else
  24. this.ruleset_match_c = null;
  25. this.rules = [];
  26. this.exclusions = [];
  27. this.targets = [];
  28. this.cookierules = [];
  29. this.active = default_state;
  30. this.default_state = default_state;
  31. this.note = note;
  32. }
  33.  
  34. RuleSet.prototype = {
  35. apply: function(urispec) {
  36. var returl = null;
  37. // If a rulset has a match_rule and it fails, go no further
  38. if (this.ruleset_match_c && !this.ruleset_match_c.test(urispec)) {
  39. log(VERB, "ruleset_match_c excluded " + urispec);
  40. return null;
  41. }
  42. // Even so, if we're covered by an exclusion, go home
  43. for(var i = 0; i < this.exclusions.length; ++i) {
  44. if (this.exclusions[i].pattern_c.test(urispec)) {
  45. log(DBUG,"excluded uri " + urispec);
  46. return null;
  47. }
  48. }
  49. // Okay, now find the first rule that triggers
  50. for(var i = 0; i < this.rules.length; ++i) {
  51. returl = urispec.replace(this.rules[i].from_c,
  52. this.rules[i].to);
  53. if (returl != urispec) {
  54. return returl;
  55. }
  56. }
  57. if (this.ruleset_match_c) {
  58. // This is not an error, because we do not insist the matchrule
  59. // precisely describes to target space of URLs ot redirected
  60. log(DBUG,"Ruleset "+this.name
  61. +" had an applicable match-rule but no matching rules");
  62. }
  63. return null;
  64. },
  65.  
  66. };
  67.  
  68.  
  69. function RuleSets() {
  70. // Load rules into structure
  71. this.targets = {};
  72.  
  73. for(var i = 0; i < rule_list.length; i++) {
  74. var xhr = new XMLHttpRequest();
  75. // Use blocking XHR to ensure everything is loaded by the time
  76. // we return.
  77. //var that = this;
  78. //xhr.onreadystatechange = function() { that.loadRuleSet(xhr); }
  79. xhr.open("GET", chrome.extension.getURL(rule_list[i]), false);
  80. //xhr.open("GET", chrome.extension.getURL(rule_list[i]), true);
  81. xhr.send(null);
  82. this.loadRuleSet(xhr);
  83. }
  84. this.global_rulesets = this.targets["*"] ? this.targets["*"] : [];
  85. }
  86.  
  87. RuleSets.prototype = {
  88. localPlatformRegexp: new RegExp("chromium"),
  89.  
  90. loadRuleSet: function(xhr) {
  91. // Get file contents
  92. if (xhr.readyState != 4) {
  93. return;
  94. }
  95.  
  96. // XXX: Validation + error checking
  97. var sets = xhr.responseXML.getElementsByTagName("ruleset");
  98. for (var i = 0; i < sets.length; ++i) {
  99. this.parseOneRuleset(sets[i]);
  100. }
  101. },
  102. parseOneRuleset: function(ruletag) {
  103. var default_state = true;
  104. var note = "";
  105. if (ruletag.attributes.default_off) {
  106. default_state = false;
  107. note += ruletag.attributes.default_off.value + "\n";
  108. }
  109.  
  110. // If a ruleset declares a platform, and we don't match it, treat it as
  111. // off-by-default
  112. var platform = ruletag.getAttribute("platform");
  113. if (platform) {
  114. if (platform.search(this.localPlatformRegexp) == -1) {
  115. default_state = false;
  116. }
  117. note += "Platform(s): " + platform + "\n";
  118. }
  119.  
  120. var rule_set = new RuleSet(ruletag.getAttribute("name"),
  121. ruletag.getAttribute("match_rule"),
  122. default_state,
  123. note.trim());
  124.  
  125. // Read user prefs
  126. if (rule_set.name in localStorage) {
  127. rule_set.active = (localStorage[rule_set.name] == "true");
  128. }
  129.  
  130. var rules = ruletag.getElementsByTagName("rule");
  131. for(var j = 0; j < rules.length; j++) {
  132. rule_set.rules.push(new Rule(rules[j].getAttribute("from"),
  133. rules[j].getAttribute("to")));
  134. }
  135.  
  136. var exclusions = ruletag.getElementsByTagName("exclusion");
  137. for(var j = 0; j < exclusions.length; j++) {
  138. rule_set.exclusions.push(
  139. new Exclusion(exclusions[j].getAttribute("pattern")));
  140. }
  141.  
  142. var cookierules = ruletag.getElementsByTagName("securecookie");
  143. for(var j = 0; j < cookierules.length; j++) {
  144. rule_set.cookierules.push(new CookieRule(cookierules[j].getAttribute("host"),
  145. cookierules[j].getAttribute("name")));
  146. }
  147.  
  148. var targets = ruletag.getElementsByTagName("target");
  149. for(var j = 0; j < targets.length; j++) {
  150. var host = targets[j].getAttribute("host");
  151. if (!(host in this.targets)) {
  152. this.targets[host] = [];
  153. }
  154. this.targets[host].push(rule_set);
  155. }
  156. },
  157.  
  158. potentiallyApplicableRulesets: function(host) {
  159. // Return a list of rulesets that apply to this host
  160. var i, tmp, t;
  161. var results = this.global_rulesets;
  162. if (this.targets[host])
  163. results = results.concat(this.targets[host]);
  164. // replace each portion of the domain with a * in turn
  165. var segmented = host.split(".");
  166. for (var i = 0; i < segmented.length; ++i) {
  167. tmp = segmented[i];
  168. segmented[i] = "*";
  169. t = segmented.join(".");
  170. segmented[i] = tmp;
  171. if (this.targets[t])
  172. results = results.concat(this.targets[t]);
  173. }
  174. // now eat away from the left, with *, so that for x.y.z.google.com we
  175. // check *.z.google.com and *.google.com (we did *.y.z.google.com above)
  176. for (var i = 1; i <= segmented.length - 2; ++i) {
  177. t = "*." + segmented.slice(i,segmented.length).join(".");
  178. if (this.targets[t])
  179. results = results.concat(this.targets[t]);
  180. }
  181. log(DBUG,"Applicable rules for " + host + ":");
  182. if (results.length == 0)
  183. log(DBUG, " None");
  184. else
  185. for (var i = 0; i < results.length; ++i)
  186. log(DBUG, " " + results[i].name);
  187. return results;
  188. },
  189.  
  190. shouldSecureCookie: function(cookie, knownHttps) {
  191. // Check to see if the Cookie object c meets any of our cookierule citeria
  192. // for being marked as secure. knownHttps is true if the context for this
  193. // cookie being set is known to be https.
  194. //log(DBUG, "Testing cookie:");
  195. //log(DBUG, " name: " + cookie.name);
  196. //log(DBUG, " host: " + cookie.host);
  197. //log(DBUG, " domain: " + cookie.domain);
  198. //log(DBUG, " rawhost: " + cookie.rawHost);
  199. var i,j;
  200. var hostname = cookie.domain;
  201. // cookie domain scopes can start with .
  202. while (hostname.charAt(0) == ".")
  203. hostname = hostname.slice(1);
  204.  
  205. var rs = this.potentiallyApplicableRulesets(hostname);
  206. for (var i = 0; i < rs.length; ++i) {
  207. var ruleset = rs[i];
  208. if (ruleset.active) {
  209. if (!knownHttps && !this.safeToSecureCookie(hostname))
  210. continue;
  211. for (var j = 0; j < ruleset.cookierules.length; j++) {
  212. var cr = ruleset.cookierules[j];
  213. if (cr.host_c.test(cookie.domain) && cr.name_c.test(cookie.name)) {
  214. return ruleset;
  215. }
  216. //log(WARN, "no match domain " + cr.host_c.test(cookie.domain) +
  217. // " name " + cr.name_c.test(cookie.name));
  218. //log(WARN, "with " + cookie.domain + " " + cookie.name);
  219. //log(WARN, "and " + cr.host + " " + cr.name);
  220. }
  221. }
  222. }
  223. return null;
  224. },
  225.  
  226. safeToSecureCookie: function(domain) {
  227. // Check if the domain might be being served over HTTP. If so, it isn't
  228. // safe to secure a cookie! We can't always know this for sure because
  229. // observing cookie-changed doesn't give us enough context to know the
  230. // full origin URI.
  231.  
  232. // First, if there are any redirect loops on this domain, don't secure
  233. // cookies. XXX This is not a very satisfactory heuristic. Sometimes we
  234. // would want to secure the cookie anyway, because the URLs that loop are
  235. // not authenticated or not important. Also by the time the loop has been
  236. // observed and the domain blacklisted, a cookie might already have been
  237. // flagged as secure.
  238.  
  239. if (domain in domainBlacklist) {
  240. log(INFO, "cookies for " + domain + "blacklisted");
  241. return false;
  242. }
  243.  
  244. // If we passed that test, make up a random URL on the domain, and see if
  245. // we would HTTPSify that.
  246.  
  247. try {
  248. var nonce_path = "/" + Math.random().toString();
  249. nonce_path = nonce_path + nonce_path;
  250. var test_uri = "http://" + domain + nonce_path;
  251. } catch (e) {
  252. log(WARN, "explosion in safeToSecureCookie for " + domain + "\n"
  253. + "(" + e + ")");
  254. return false;
  255. }
  256.  
  257. log(INFO, "Testing securecookie applicability with " + test_uri);
  258. var rs = this.potentiallyApplicableRulesets(domain);
  259. for (var i = 0; i < rs.length; ++i) {
  260. if (!rs[i].active) continue;
  261. var rewrite = rs[i].apply(test_uri);
  262. if (rewrite) {
  263. log(INFO, "Yes: " + rewrite);
  264. return true;
  265. }
  266. }
  267. log(INFO, "(NO)");
  268. return false;
  269. },
  270.  
  271. rewriteURI: function(urispec, host) {
  272. var i = 0;
  273. var newuri = null
  274. var rs = this.potentiallyApplicableRulesets(host);
  275. for(i = 0; i < rs.length; ++i) {
  276. if (rs[i].active && (newuri = rs[i].apply(urispec)))
  277. return newuri;
  278. }
  279. return null;
  280. },
  281. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement