Open hakanson opened 8 years ago
This sounds like an excellent idea. Although I am wondering if the safest path is to encourage people to use a published version. Isn't it better that a developer downloads a copy of the library, checks that it is valid and then generates their own SRI? That way they know for sure what content they are receiving.
I agree it is best to download a copy and serve it yourself. However, many tutorials reference a CDN and if you use the Google CDN it is likely the browser gets a cache hit.
I was brainstorming that on every "release" (e.g. 1.4.9, 1.5.0, 1.5.1, etc), the integrity hash values could be generated and put into a SRI.json file. Those values could be used to both feed the documentation and used as input into a grunt/gulp/whatever build task for projects using angular.js to add the integrity attribute to script tags.
I'm not sure of the best solution, nor know of other libraries to look at as examples, but wanted to raise as an issue for the discussion on what to do.
I'm not sure that I agree it's better to host your own copy as that can result in a worse experience for the user in a few ways. Using an asset from a CDN increases the chance that the user will already have it in their cache, reducing bandwidth requirements and potentially cost. This also improves performance which results in a better UX. SRI resolves the trust issue of allowing a 3rd party to serve your assets.
Many projects already provide checksum/integrity values for their downloads and SRI is, in effect, a method of automating that process in the browser. If we can't trust the integrity values provided by the project then we have greater concerns. Also, is a developer realistically going to review the entire Angular code base before generating their own integrity value?
The only addition I'd make here is that the provided script tags for each release should include more than the sha384 integrity value. A browser will always chose the strongest hash that it supports so it could be a good idea to include the sha256 and sha512 values for backwards and forwards compatibility too. As Kevin mentioned, there are simple methods to produce these values and include them in documentation for wider circulation.
I wasn't suggesting that one hosts their own copy. I was just saying that if you can't rely upon the CDN being valid then why should you rely upon us providing a valid hash? I was suggesting that you use the CDN but then generate your own hash from a copy downloaded from the CDN that you have confirmed is valid.
We will discuss this in the team meeting today and come up with a plan.
Ok, self hosting aside as that seems to have taken us off topic, we still need to depend on you guys to provide the hash.
If we download a copy from a CDN where and how do we validate that? We're going to turn to you guys and say 'is this valid?'. That's exactly what integrity hashes are for, both in the context of SRI and otherwise. You as the author define the hash that all others are checked against. Failing that I'm not sure what other method we have to validate the file.
OK, so we discussed this in our team meeting. Here is the plan:
angular.min.js
to the download button on https://angularjs.orgIs this acceptable? PRs are most welcome :-)
What were you thinking for file extension and format? I initially thought of the .md5
and .sha1
style extensions, but would you want to generate .sha256
, .sha384
, and .sha512
files? Also, a file with that style extensions would appear to be compatible with shasum
but the shasum
utility generates hex values and includes the filename.
shasum -a 384 angular.min.js
857348f426fc3890b7faad74b440bb454cda0c458a8c8422135960fad148aedb5e7c81be49c5022aa3a541512a726334 angular.min.js
I am wondering if you should generate an .integrity
file with all the valid prefixed and base64-encoded hashes? Here would be an example of angular.min.js.integrity
sha256-RPPsQcSPq5bHR3vDUWpr9XR/NHMe9QAJ8Uwffw3LBDM=
sha384-hXNI9Cb8OJC3+q10tEC7RUzaDEWKjIQiE1lg+tFIrttefIG+ScUCKqOlQVEqcmM0
sha512-y2SOwfsp2w/M2K9LzWRyFd/V62w3z9frSvAB96p7AJlyNIF7O40A6ezctVEgyI2gap6ikSoFpSrtC8Gztmjp4A==
The contents from a file like this could be used directly by IDEs or build tasks to insert / verify the value of the integrity
attribute into the script tag.
I like the idea of the integrity file, I would consider going further and just provide the full script tag in those files... My motivation is that really what we want is to make it super-simple for developers to use the integrity values, right?
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"
integrity="sha256-RPPsQcSPq5bHR3vDUWpr9XR/NHMe9QAJ8Uwffw3LBDM="
crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"
integrity="sha384-hXNI9Cb8OJC3+q10tEC7RUzaDEWKjIQiE1lg+tFIrttefIG+ScUCKqOlQVEqcmM0"
crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"
integrity="sha512-y2SOwfsp2w/M2K9LzWRyFd/V62w3z9frSvAB96p7AJlyNIF7O40A6ezctVEgyI2gap6ikSoFpSrtC8Gztmjp4A=="
crossorigin="anonymous"></script>
Yeah, I like the idea of the full tag being generated, it's less work to implement then. It's also worth noting that you can/should specify multiple integrity attributes in the same tag and the browser will automatically select the strongest it supports. This allows for wider support of SRI in various browsers and reduces the problems if support for a hash were to be dropped due to future events.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"
integrity="sha256-RPPsQcSPq5bHR3vDUWpr9XR/NHMe9QAJ8Uwffw3LBDM="
integrity="sha384-hXNI9Cb8OJC3+q10tEC7RUzaDEWKjIQiE1lg+tFIrttefIG+ScUCKqOlQVEqcmM0"
integrity="sha512-y2SOwfsp2w/M2K9LzWRyFd/V62w3z9frSvAB96p7AJlyNIF7O40A6ezctVEgyI2gap6ikSoFpSrtC8Gztmjp4A=="
crossorigin="anonymous">
</script>
This is covered in the SRI spec: https://www.w3.org/TR/SRI/#agility
I like the idea of making it as simple as possible, because I fear most developers won't take the time to figure out how to use the raw integrity hash data.
Is there a concern this "unfairly" promotes the Google CDN. If a user happens to use a different CDN host like cdnjs, they need to change the src
. I don't think there is an issue, but wanted to raise the point.
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"
integrity="sha256-RPPsQcSPq5bHR3vDUWpr9XR/NHMe9QAJ8Uwffw3LBDM="
integrity="sha384-hXNI9Cb8OJC3+q10tEC7RUzaDEWKjIQiE1lg+tFIrttefIG+ScUCKqOlQVEqcmM0"
integrity="sha512-y2SOwfsp2w/M2K9LzWRyFd/V62w3z9frSvAB96p7AJlyNIF7O40A6ezctVEgyI2gap6ikSoFpSrtC8Gztmjp4A=="
crossorigin="anonymous">
</script>
@hakanson well it is a Google project :-)
Were you thinking of using the grunt-sri payload.json format?
{
"payload": {
"@angular.min.js": {
"path": "angular.min.js",
"type": null,
"integrity": "sha256-RPPsQcSPq5bHR3vDUWpr9XR/NHMe9QAJ8Uwffw3LBDM= sha384-hXNI9Cb8OJC3+q10tEC7RUzaDEWKjIQiE1lg+tFIrttefIG+ScUCKqOlQVEqcmM0 sha512-y2SOwfsp2w/M2K9LzWRyFd/V62w3z9frSvAB96p7AJlyNIF7O40A6ezctVEgyI2gap6ikSoFpSrtC8Gztmjp4A==",
"hashes": {
"sha256": "RPPsQcSPq5bHR3vDUWpr9XR/NHMe9QAJ8Uwffw3LBDM=",
"sha384": "hXNI9Cb8OJC3+q10tEC7RUzaDEWKjIQiE1lg+tFIrttefIG+ScUCKqOlQVEqcmM0",
"sha512": "y2SOwfsp2w/M2K9LzWRyFd/V62w3z9frSvAB96p7AJlyNIF7O40A6ezctVEgyI2gap6ikSoFpSrtC8Gztmjp4A==",
}
}
}
}
it seems more robust that the gulp-sri JSON
{
"path/to/file/relative/to/project/root/filename.ext": "srihash",
//other entries
}
grunt-sri looks like a good option
PR anyone??
I started a bit of PR for this....
I don't think there is a great deal of interest in doing this.
https://docs.angularjs.org/misc/downloading which is sourced from downloading.ngdoc contains a "Including angular scripts from the Google CDN" section with this example for downloading from the Google CDN server:
With Subresource Integrity available in some browsers, should this example be updated to include an
integrity
attribute?This value was determined by downloading the minified 1.4.5 file and computing the hash using:
This is a good suggestion from a security perspective, but requires the documentation to be updated with a new
integrity
attribute along with every version change. It also would require the developer to understand the purpose of this attribute value, because if they copy that example and only change1.4.5
to1.4.6
, the script will not load and the developer will get a potentially confusing error in the Console like:However, I would like to see the hashed for Subresource Integrity published somewhere, even if the Download documentation isn't the right place.