Type: other
cc @jsha @pde @J0WI @diracdeltas @jeremyn @gloomy-ghost @Bisaloo
I plan on making this the release that incorporates the sign-rulesets branch.
Where can I download an example of an intermediate ruleset update, if that's active yet?
@jeremyn sign-rulesets only has full ruleset delivery. I'd love to get a functioning branch for intermediate updates in the near future. I don't see why we couldn't gracefully move to intermediate updates, so I'm leaving that for a later iteration.
By intermediate ruleset delivery I mean that it downloads rulesets, whether all 20k+ or just what's changed, from some EFF URL. In other words "intermediate" meaning "between full extension releases", not "intermediate" meaning "less than the full number of rulesets", in case that wasn't clear.
@jeremyn I don't have this available just yet, but I should have the actual URL we'll be using within the extension available in the next few days.
@Hainish So we're on the same page: my understanding of sign-rulesets is that it downloads a ruleset collection from some URL, say https://eff.org/rulesets.zip , confirms its integrity somehow, and then replaces/updates the existing set of rulesets with what's in the collection.
I'm interested in downloading rulesets.zip manually and taking a look at it, and I asked you for the URL for it, and you said you're going to create one.
Is that right? If so, how have you been testing so far? An internal/local server?
@jeremyn yes, that's all correct (though it's not a zip file). I've been signing the rulesets via utils/sign-rulesets-standalone.sh and serving the generated ruleset files via python -m SimpleHTTPServer, modifying chromium/background-scripts/update_channels.js to the appropriate local values.
How will this work in the Tor browser? They don't allow any connection like this.
@J0WI the Tor Browser transparently proxies any connections made from extensions. The downloads will go over Tor. You're not able to test this with a localhost connection, however. You have to post the rulesets on a publicly accessible endpoint.
It's not a technical limitation, it's a design decision by the Tor Project.
Add-On updates, Safe search, telemetry etc. are all disabled.
@J0WI add-ons have always been able to be updated from within Tor Browser. Can you link me to a specific design document specification where this is blocked?
I've changed the estimated release date to 2018.4.2 to give enough lead-up time to coordinate with our press team at EFF.
@Hainish it's hard to find this again, but I think https://trac.torproject.org/projects/tor/ticket/10394 is the right one.
First attempt to disable updates was here but this has been reverted due a regression.
@J0WI this is for updates to the extension itself, rather than the rulesets. A lot of the motivation for pinning the version comes from a lack of trust in the AMO updates process, see https://hackernoon.com/postmortem-of-the-firefox-and-tor-certificate-pinning-vulnerability-rabbit-hole-bd507c1403b4. Delivery of rulesets out-of-band from the extension itself makes it so that if the Tor Browser pins the version of the extension, as it looks like they might do, users will still have a recent version of the rulesets. The ruleset updates would not be blocked by Tor Browser.
@Hainish But like @J0WI said in https://github.com/EFForg/https-everywhere/issues/14907#issuecomment-373927604, it's a question of design, not current technical behavior. If the Tor Browser project blocks, or should block, all self-updating mechanisms as a design goal, then this new self-ruleset-updating functionality will cause a problem for them.
The ticket https://trac.torproject.org/projects/tor/ticket/10394 that @J0WI linked refers to disabling "update pings" and doesn't make the distinction you are making between extension updates and ruleset updates. It also considers "updates from EFF or AMO" (italics mine) as problematic, not just AMO.
Is there a specific statement somewhere that says the Tor Browser developers approve this new self-ruleset-updating functionality? It would be awkward if they have to, for example, rush through an emergency change to block this functionality. The current last comment from cypherpunks in the Tor ticket says
Hainish says it should hopefully be ready for the 2018.3.27 release:
I plan on making this the release that incorporates the sign-rulesets branch.
​
https://github.com/EFForg/https-everywhere/issues/14907
but I'm not sure if we should interpret that as approval.
@jeremyn the Tor Browser design document is the relevant reference for updates. In it, there is a section that explicitly addresses the safety of Mozilla updates. As such, the answer to the question of whether
the Tor Browser project blocks, or should block, all self-updating mechanisms as a design goal
is a definitive "no."
I've also in conversation with the Tor Browser developers mentioned the out-of-band ruleset updates, it didn't seem to be an issue of concern for them in the past. They are aware this change is forthcoming, and I've reached out to them with the announcement of the 2018.4.2 release.
Your above quote about "updates from EFF or AMO" is in a discussion directly related to updates of the entire extension. I'm aware of this discussion, and in fact the --remove-update-channel flag I added myself in https://github.com/EFForg/https-everywhere/commit/aae154af4f495ddaa4c48a9aea8acc0bd50252bc. It used a technique originally suggested to me by the Tor Browser lead dev, but it looks like it was removed due to unexpected errors being thrown. Out-of-band ruleset delivery is a separate concern, and I've reached out to the Tor Browser once again to notify them of this change and see if they have any concerns.
@jeremyn the ruleset URL: https://www.https-rulesets.org/
To test with this, you'll have to apply the following diff to sign-rulesets:
diff --git a/chromium/background-scripts/update_channels.js b/chromium/background-scripts/update_channels.js
index 834f746..e3fea27 100644
--- a/chromium/background-scripts/update_channels.js
+++ b/chromium/background-scripts/update_channels.js
@@ -7,7 +7,7 @@ var update_channels = [{
jwk: {
kty: "RSA",
e: "AQAB",
- n: "1J6QHCKf7zOkIXLs0pUF0KLy-RlTtXmNhj3OkQMULbQagciDl9ppm1swXHAYi718uoILU_fUzdk8QObXmKVuRMjs7NiXbFOeT0teQou1sX99k-WEJM8SlkXCJDCtYSWnLiadtRCdd1FrjMJcGcMYD_38CcnRBZZOt0PWtoUPMyDX-OUHMd8fQ_b78g-TThmQRxGsQfjYdM7_Hn_djnVON_Iik_lYw9SSazy9GzEJO3naMG2j47NAD8CFBwqqCI9kHkqCqirDDMVIT9ZxoyOFBWBFq4EErKyAjP3l2AD05aCwOPTwVnRfIRPJP6SoCv31e76M41_xsodbICueVWgWP1yRuwxwHNmqPRMhkEA_ZP6R7MpsJP9HLBnPXm9_k4QFndyIdYNgo08cgZTkQcY5y-paOJW5aFzJhxnbC1NQ6AebQyCd-meFVNBiyw3CkI_TsItLgaRSQNzBLgE7Of5aYLk3_cO0rZDfvbo5QzrDXmKym57mhPl01YYUzHyAdWELrvs6hJxwsCROHXCwSqHBtJU5-nPEBgHgAhzc8iH7zVOwL3i1oyPvE0E8UK6eg80FUdwI6iu01-doJywBLD5DOyH2D0ErZNTiAcTkHtAxuxlmbRneaxP2_JqX4WwC1CNyccPp1VzwGFWVlu0rEODPuUm0zkPXPDB0D_0PjHvP_wU"
+ n: "uEjp9igRAr7fl2Ekiohyorx50O3nAu0WDn9ViNJZlDJ5GPPhN7C7hvAUBIpZBPAtEmFNG1fLzfravgtJFtqX5IK7ty-QpKJnSCsD5xANwFX8_fQN4hB16QW1XzMz8JUJJge6zD3o6niiRogeaQdtMzLvWmIeYoHTrIhp-2j0aWqPTd0KGLCtlHnDJ4qW9npWB6Lf6FucBZsyXNcXW2rWvEl4j20vLWjKANbVGiUTRF1ngqyMgmOUWdS2miq6tG7IZBdFkEg1G6mSWWOjf2IKpA5C6PHpQBOdzO_vj-tChwncj4EmvQXZohRK5Cm7ZPP1OA5AdSFpXcGQt2LRzuZEtFNTaK4H4zisITf7RN9PorED5WK4PiYXygDMdbMF3E65A4RG-LcYEqVKs1DzSaxrmcLmK_yV7tDdh1SMbboJlz3kPJEyYNKP77wLY_K3-7ZZlUpHWebz0X78LWfJVmn0kE9mA5Thc4ZRBtI5O0VC1dXI5t4gRuiOJTJQKxXepBfY7q49gLjYGOzHrx5Y8n2N1ui5j1A-avYzJL7xs9SzJPPY3lRt9BXZpFEgBcD56zy1Mqw7V9ResPSvOjt2wogLs8QxrBnVMgJNhP_BZPTPaPQq4d690ykeL7pj_hFaa8mL7OaCqY1VExuxJ-P3q7KUa-QszOUYY7BZ7yKG-8zYvsM"
},
- update_path_prefix: "http://localhost:8000"
+ update_path_prefix: "https://www.https-rulesets.org/"
}];
@Hainish can you manage to set up HPKP and DNSSEC for www.https-rulesets.org? (like AMO and Torproject.)
Also this host is not compatible to preloaded HSTS requirements (cert is not valid for https-rulesets.org, no redirect to HTTPS, HSTS header sent on HTTP).
Or even better: could you provide this as an onion service?
Are the sources manually uploaded or is there any backend that can be published?
I would like to learn a bit more about the sign/verify process. Is this already documented somewhere?
I don't see an advantage to providing this as an onion service, given the integrity checking on the user's side.
I think the rulesets should be provided under the eff.org domain, so users know it's reputable.
The build process is probably https://github.com/EFForg/https-everywhere/blob/master/utils/merge-rulesets.py and then something from https://github.com/EFForg/https-everywhere/tree/sign-rulesets/utils/sign-rulesets , but I'd like to hear the details too.
@J0WI we are still in the process of setting this site up. It will be included in the preload list, but will not have HPKP. What specific threat do you have in mind that would be mitigated by inclusion in HPKP? In this very specific case, I honestly don't see very much utility even in providing updates over HTTPS. We will do so anyway, but what does this mitigate against? Since updates are verified by the client, you are in no danger of applying a malicious update delivered over HTTP. At worst, a MITM would be able to trick clients into thinking there is a new update more often than there actually is, in an uncertain attempt to increase bandwidth for the site and cause a denial of service. One could argue that with HTTPS, you'd have to compromise two keys - one, the HTTP server, and two, the RSA key that is used for updates. But the weakest link is the HTTPS key, which is stored on a network-accessible server, rather than protected with an airgapped signing process. Compared with the RSA key, it provides little protection. Short of a compromise in RSA itself, HTTPS won't provide you with much extra security. And if RSA is compromised, we will all have more fundamental internet security infrastructure to worry about.
The signing scripts are located in https://github.com/EFForg/https-everywhere/tree/sign-rulesets/utils/sign-rulesets. These can be pointed at the default.rulesets file (generated by merge-rulesets.py as @jeremyn points out) to generate the three files that you see on https://www.https-rulesets.org/. This is manually uploaded to that site. Simple as that. I was planning on adding some documentation for this sometime after deploying it.
@jeremyn the choice of a non-EFF domain to do ruleset delivery was a result of community input. I understand your point, but my reasoning is explained in https://github.com/EFForg/https-everywhere/issues/12606#issuecomment-358424399
The other attack scenario is simply denying any request to the rulesets on https://www.https-rulesets.org/, since you can see the specific requests being made. However, since that is a single-serving site, you can simply deny any requests made to that entire domain (via DNS or simple IP blocking). So HTTPS gives you no win there, either.
Georg (Tor Browser lead) says:
Thanks and nice to see this feature emerging, I'll take a look.
Since updates are verified by the client, you are in no danger of applying a malicious update delivered over HTTP. At worst, a MITM would be able to trick clients into thinking there is a new update more often than there actually is
If this is served over HTTP, couldn't you also perform a MITM to trick clients into thinking there is no update? This could be an issue.
I agree preloading the domain is the right mitigation for this threat.
IMHO, https://www.https-rulesets.org/v1/default.rulesets.gz.base64 with API version specified in the URL is better than just plain https://www.https-rulesets.org/default.rulesets.gz.base64 . Otherwise, the out-of-band updates might break older clients when there is breaking changes in the format of default.rulesets .
@Hainish Right, we had the discussion about hostile actors potentially blocking eff.org. The other domain makes sense now. You might consider adding a README to the root of https://www.https-rulesets.org explaining what the site is for, for people who end up there by watching their outbound network traffic.
We should provide the rulesets over HTTPS as a matter of principle, since this is the HTTPS Everywhere project. But I agree with @Bisaloo that a MITM could break the updates even if they couldn't create new ones. Another strategy would be to corrupt the signature file so HTTPS Everywhere thinks the updates are always broken.
About the RSA key, an attacker doesn't need to break RSA generally, just the implementation that some particular version of HTTPS Everywhere uses, or a downstream redistribution of HTTPS Everywhere. This could be a serious problem for users with that old version that don't update the extension for whatever reason.
@cschanaj Another option is to upload all of the default.rulesets files marked with a SHA256 hash, like default.rulesets.0123abcd..., and keep them up there indefinitely. Instead of a rulesets-timestamp, there could be rulesets-current-version with the hash, and HTTPS Everywhere checks whether the hash for its current rulesets matches the hash in that file. Maybe rulesets-current-version could be a JSON file that has both the hash and the v1 marker you're suggesting.
If this is served over HTTP, couldn't you also perform a MITM to trick clients into thinking there is no update? This could be an issue.
My point is that a MITM can break updates anyway, even with HTTPS, since they can just block the IP or DNS queries to the rulesets domain. No amount of HTTPS will protect you against that.
And just to be clear, as I said, we are deploying with HTTPS and having submitted to the HSTS preoload list. This is just an exercise in threat modelling.
It won't actually be included in the preload list by the time we deploy, since that takes some extra time. This won't be an issue, since we will explicitly list the URL as "https://www.https-rulesets.org/" in update_channels.js.
@jeremyn the reason I like timestamps is that it prevents downgrade attacks. An attacker with server access could trick the client into applying an old version of rulesets by simply switching the rulesets-current-version file for an older one. This is potentially more harmful than a simple DoS, which wouldn't result in downgraded rulesets. I think a better solution would be to switch to timestamped filenames, and include the timestamp within the body of default.rulesets, which is signed. The client only applies rulesets with timestamps which are larger than the one currently applied.
I also like the fact that when listing the filenames in the named by timestamp case, they will be listed chronologically by the server.
I've changed the directory structure to include v1 as @cschanaj suggested, as well as uploading the public key in a keys path. I've also changed sign-rulesets to download the signature and gzipped default.rulesets file directly, rather than a base64 encoding of those files, switching from XMLHttpRequest to the buffer-oriented fetch. This will shave ~400k off of every rulesets download. https://www.https-rulesets.org/
I don't see an advantage to providing this as an onion service, given the integrity checking on the user's side.
Avoiding traffic and analysis on exit nodes. I think both are very important for the Tor network.
The other attack scenario is simply denying any request to the rulesets on https://www.https-rulesets.org/, since you can see the specific requests being made. However, since that is a single-serving site, you can simply deny any requests made to that entire domain (via DNS or simple IP blocking). So HTTPS gives you no win there, either.
That would also be fixed with an onion service.
What specific threat do you have in mind that would be mitigated by inclusion in HPKP? In this very specific case, I honestly don't see very much utility even in providing updates over HTTPS. We will do so anyway, but what does this mitigate against?
That's simply to have the same level as Tor and Mozilla have. Both are also signing their software.
You might consider adding a README to the root of https://www.https-rulesets.org explaining what the site is for, for people who end up there by watching their outbound network traffic.
+1, with a link to GitHub/EFF and maybe a statement that you're not logging any requests on that host etc.
Just to clarify: will rulesets still be bundled with add-on updates? So the worst case is, that you get new rules (only) with new releases?
@J0WI let's consider an onion service in a separate issue. I don't really consider it MVP for this release, but happy to discuss it for down the line.
Yes, rulesets will still be bundled with the extension itself. If https-rulesets.org becomes inaccessible, users will still get new rules with new releases.
@Hainish I agree with your point about downgrade attacks.
I think we can ensure maximum future flexibility by using this scheme for updates:
instructions.jsoninstructions.json which contains two general types of information: metadata to decide whether a ruleset update is needed (hash, timestamp, version, some other flag), and a URL for where to go get the updated rulesetsinstructions.json and then updates itselfIn the above system, any reference to one URL should be read as all URLs needed for one download, such as default.rulesets and default.rulesets.sig.
Some important advantages of this system include:
v1/instructions.json file, as long as different versions of HTTPS Everywhere can each read the fileRegarding HPKP, Chrome is planning on deprecating and removing it, so (for better or worse) it's not something we should really worry about having on the server.
Regarding HPKP, Chrome is planning on deprecating and removing it
I think Tor have different priorities... Also Mozilla itself didn't announced to drop this feature too, but they started to support it on their own services.
I think that the rule should be that the sign-rulesets updates should be at least as secure as however users download the full extension. So if AMO or the Tor Project uses HPKP, then the sign-rulesets updates should too. At least, the burden of argument for using HPKP shouldn't fall on @J0WI or anyone else asking for HPKP.
So, I agree with @J0WI here.
I've prevented the downgrade attack scenario in https://github.com/EFForg/https-everywhere/commit/fcf9f103b4e4c5decfa07a69f63dba5e9fd3cc59:
Protect against downgrade attacks. A sophisticated attacker would
previously be able to switchdefault.rulesets.gzwith an old signed
ruleset file. We now combine the fact that the JavaScript checks that
latest-rulesets-timestamphas a greater value than what is currently
stored and, vitally, that it matches the timestamp bundled with the
signed ruleset file.
I've added timestamped filenames with this as well. I'd like to keep our schema simple. The advantage of having a latest-rulesets-timestamp file as the heartbeat is that it's a very small file. With 2M+ weekly chrome users and close to a million daily Firefox users (plus who knows how many Tor Browser users) I'd like to keep the bandwidth strain low when we have no new updates.
@Hainish I'm not sure if your "small file" comment was against my instructions.json recommendation, but if so:
Assume we have three million daily users and are comparing
latest-rulesets-timestamp (11 bytes): 1234567890
with
instructions.json (about 200 bytes):
{
"timestamp": 1234567890,
"url": "https://www.https-rulesets.org/v1/default.rulesets.1234567890.gz",
"signature": "https://www.https-rulesets.org/v1/rulesets-signature.1234567890.sha256"
}
Monthly download bandwidth for latest-rulesets-timestamp is about 1GB/month, and for instructions.json it's about 18GB/month. Current AWS S3 download bandwidth pricing is $0.01/GB.
So, latest-rulesets-timestamp saves about 17 cents per month relative to instructions.json, at least with these assumptions. I don't think saving bandwidth is a strong argument for using one approach instead of the other.
It seems to me that downstream projects will not be able to utilize this endpoint if they would like to have deterministic builds/ pinned versions. Not sure if EFF should entertain them or not in this endpoint or another. Besides, IMHO it might also worth to include the ruleset version inside default.rulesets itself.
@cschanaj As far as I know, downstream projects should be able to use and verify these rulesets if they want, or they can disable these automatic updates entirely or by default.
@cschanaj the extension itself will still be reproducible, and the rulesets can either be verified directly using the HTTPS Everywhere signing key, or they can modify the update_channels.js file to provide their own endpoint with their own rulesets (possibly just an audited version of ours) and verify ruleset delivery with their own keys, if they don't trust ours.
Pushing this to tomorrow to finish up a few loose ends (https-rulesets.org home page, ensuring updating does not occur if the extension version > the rulesets version for the "EFF (Full)" update channel.
Georg from Tor Browser has looked through our signing code, and had some feedback which I incorporated into sign-rulesets.
Release made!
@Hainish Congratulations on getting the sign-rulesets feature out! I've argued against it before, but I want to acknowledge that it has taken a lot of work and planning from you and others to get to this point, and that you and others should feel proud for launching it. Now that the project has committed to it, I wish it well.
Thank you @jeremyn, I really appreciate the well-wishes!
Most helpful comment
IMHO,
https://www.https-rulesets.org/v1/default.rulesets.gz.base64with API version specified in the URL is better than just plainhttps://www.https-rulesets.org/default.rulesets.gz.base64. Otherwise, the out-of-band updates might break older clients when there is breaking changes in the format ofdefault.rulesets.