caution.addSafe(['8208dd7d61227d3c...', ...]);caution.addSafe(function (code, hash) {return hasValidSignature(text);});
caution.addUrls('http://my-site/modules/{}.js');caution.addUrls({'some-module': 'http://my-site/js/some-module.js'});caution.addUrls(function (moduleName, versions) {return [...];});
caution.missingModules(function (moduleName) {caution.load(moduleName);});
var config = {paths: ['http://my-site/modules/{}.js'],load: {'caution': ['a675f11c3c85cc...', ...],'my-initial-module': ['8208dd7d61227d3c...']}};
var inlineJs = caution.inlineJs(config);var dataUrl = caution.dataUrl(config);
I haven’t looked with significant depth at everything but here is some feedback:
My TL;DR version is, unfortunately, “this is a solved problem and this approach is not the right way to do it”, but I do want to commend you for looking at things through the lens of security. By doing so you are ahead of the majority of software developers. :)
For performance, you should not be using third-party CDNs and should build all your code + deps into a single file at production time. Coincidentally, doing this eliminates any need to try to hash and discover “known good” versions of dependencies from untrusted parties since the source code is guaranteed to be correct. (If your build/deploy part is not secure, nothing else matters, since someone could just modify your “known good” hash set, or break your copy of caution.js, or anything else.)
For security against tampering in transit, you simply need to transmit using HTTPS with HSTS. If you do this, barring breakthroughs in crypto or a major CA compromise, the code you are transmitting is secure from the server, so again there is no reason to try to hash on the client to verify the code is good—the secure transport layer ensures that it is good. If you do not transmit over HTTPS, nothing you do will prevent tampering, since your “known good” hash set can just be changed again (or the verification function changed to always return `true` or any other thing).
To guarantee someone is loading the “right” version of code given only a saved HTML file, well, first of all good luck not having a totally broken page when someone tries to do this due to `file` protocol restrictions :), but also you can just generate versioned URLs (most AMD loaders let you do this easily with a `cacheBust` property or similar) and either maintain those files or output new code that notifies users that things are out-of-date when a newer version is available on the server. (While I won’t say it’s not a valid use case, in 15 years I can’t recall ever hearing something like this, so it sounds pretty specific to whatever you’ve been working on.)
With regards to the implementation, which I briefly glossed over, one serious and unresolvable problem stands out. This script verification approach can only work by loading the code first as data via XHR and then manually evaluating the string after it has been hashed. This means:
1. This code won’t work for browsers without XHR2 (probably OK),
2. This code won’t work for CDNs without permissive CORS policies (maybe OK),
3. You’ve broken the ability of sites to enable CSP on the domain that loads caution.js (not OK).
Since we have already discussed how to easily solve the issue of code verification via the transport layer, using caution.js actually reduces the ability for sites to secure themselves since they will be unable to enable CSP. And that is a fatal problem for a library that is supposed to improve security.
An example might be a secure messaging app. Say I visit a site and create a public-key based "vault" which I can decode, but others can post to, where the server stores the messages in encrypted form. If the server can change the JS, then it can provide a broken client that posts messages in the clear, or uploads my private key once I've unlocked it. However, if the user has the ability to watch for server changes, then the server could of course remove the service
--
You received this message because you are subscribed to the Google Groups "amd-implement" group.
To unsubscribe from this group and stop receiving emails from it, send an email to amd-implemen...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.