WICG / signature-based-sri

Signature-based Resource Loading Restrictions
https://wicg.github.io/signature-based-sri/
Other
23 stars 3 forks source link

Explainer: Signature-based Resource Loading Restrictions

The Problem

Developers wish to have fine-grained control over the resources loaded into their pages in order to mitigate the risk that malicious resources will be loaded. They have a few options to do so at the moment:

These existing mechanisms are effective, but they also turn out to be somewhat onerous for both development and deployment. Policies that restrict sources of content need to be quite granular in order to meaningfully mitigate attacks, which makes robust policies difficult to deploy at scale (see "CSP Is Dead, Long Live CSP! On the Insecurity of Whitelists and the Future of Content Security Policy for more on this point). Hash-based solutions, on the other hand, require pages and the resources they depend on to update in sequence, which again makes deployment difficult.

The proposal

We've discussed mixing signatures into SRI on and off for quite some time (and folks have been discussing bringing them into HTTP in general for much longer). They make a different kind of guarantee than hashes do (provenance of a resource as opposed to its content), but address some of the original use cases for SRI while being significantly less brittle in the face of updates (depending on the use case, of course, this flexibility might be a bug or a feature :) ).

A simple approach to layering signatures into the platform would be to extend Subresource Integrity to support validating a resource's signature, as opposed to its content. That is, a developer might specify one or more Ed25519 public keys in an integrity attribute:

<script src="https://my.cdn.com/whatever.js" integrity="ed25519-[base64-encoded public key]" crossorigin="anonymous">

The developer can sign whatever.js when they deploy it, and teach their servers to transmit a signature along with the resource in any number of ways1. For simplicity's sake, let's say that the signature is delivered in a response header which the user agent could verify before executing the script. This might look like:

HTTP/1.1 200 OK
Accept-Ranges: none
Vary: Accept-Encoding
Content-Type: text/javascript; charset=UTF-8
Access-Control-Allow-Origin: *
...
Integrity: ed25519-[base64-encoded result of Ed25519(`console.log("Hello, world!");`)]

console.log("Hello, world!");

This mechanism has some interesting properties:

FAQs.


  1. For example: the signature could be inline in the resource's body via an encoding like Web Packaging proposes. Or, the signature could be part of a manifest that contains lots of signatures for an origin. Or it could be a resource specified by a Link header. Or part of the server's TLS certificate! Or an etag! Etc! ↩︎