-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signed content should include resource names #5
Comments
I agree with you that this is a risk of signature-based mechanisms that doesn't exist with content-based mechanisms like hashes. It sounds like you'd suggest including more data in the signature in order to ensure that we're loading the thing we think we're loading: what do you think is necessary? That is, let's extend your example a bit, say Should we reconsider including other headers, like /cc @otherdaniel, who I'd like to get more involved in the design discussions. |
I like the given example. I imagine it could be quite realistic, e.g. with a development and a release version, which - for some types of setups - differ in their authentication requirements. But I don't see how to assert the URL, without making life hard for CDNs. I guess since signatures are effectively a relaxation of the integrity constraints, one puts an awful lot of trust into the key holder to relax to exactly the right set of files, where "exactly the right" would likely depend an awful lot on the specific use case. One "solution" might be a "best practices" doc, that spells out quite clearly that with signatures all same-key-signed resource are effectively interchangeable, and if that's not desired, authors need to either change their signing practices (use more keys) or solve the problem inside the source files (e.g. declare a version number inside each signed script, and then have the main resource check the version numbers.) Alternative: Maybe we could divorce the CSP header from the integrity attribute. That is: If the whole point of signature-based integrity is to strengthen the existing integrity checks by allowing for an out-of-band info in the CSP header, then maybe we should allow the resource to specify a specific subresource (with a hash), and the CSP header to specify a key. That way, the page would still reference a specific byte sequence (making rollback attacks or jyasskin's example impossible). The CSP header would then have the weaker-but-more-encompassing guarantee that all resources need to (additionally) be signed by a specific key. That way, the page author can switch resources any time without running into trouble with the CSP policy, and the CSP policy would provide a meaningful guarantee about provenance without weakening the page's intended guarantees. Or, in other words, add the signatures to the hashes, rather than replace the hashes. |
We talked about this a little bit at lunch, and I like the idea of allowing signatures and digests to be used side-by-side. That would be a mechanism for addressing the underlying issue Jeffrey is pointing to here, but also rollback attacks that we're discussing elsewhere. My understanding of the suggestion is something like the following:
Practically, I'm not sure many folks would use this mechanism, but it might be valuable enough for specific services to do the extra work. |
I'm nervous about signing just the path without its origin, although I think it is comprehensible to tell developers that their private key needs to be scoped to a set of "equivalent" origins. This sort of thing is probably why certificates were invented: once you're attaching metadata to a public keypair, it's better for that to be explicit than implicit. I could also imagine signing that a given body can be served as any of a list of names, but that does make things more complicated. Are signatures intended to strengthen hash-based checks (by allowing the signing key to live offline, for example, which would need to be mentioned in the explainer), or are they intended to weaken them a bit so that resources can be upgraded without having to update the whole tree of dependers at the same time? Requiring both a hash and a signature only helps the first, and to really solve that problem, we need a way to communicate the public key that's not vulnerable to online keys leaking. |
Both, I take it. The intention is to strengthen checks by forcing a check in a CSP, or maybe in an Origin Policy (in a future where that exists). But if you do that, you have a deployment issue, because then you would need to update your CSP/OP on every change of every sub-resource, which likely makes your deployment difficult. Having all of this based on signatures (rather than hashes) would hopefully make that more viable. So, signatures would relax things a bit, in order to allow strengthening via CSP & friends. The explainer mentions this, but doesn't call much attention to it, in the paragraph beginning with "Signatures can be layered on top of ..." |
Right, so if hashes are difficult to deploy, then "add the signatures to the hashes, rather than replace the hashes." is also difficult to deploy and doesn't solve the problem signatures were originally meant to solve. |
Naaah, disagree. The thing is, the signatures and the hashes would be in different places, where they fulfill different roles, and have different impact on deployability. Strawman:
This scenario does assume that main resource + subresource are tightly coupled and will be released together; while CSP/OP are more loosely coupled with different life-times (and, in large organizations, different teams maintaining them). Having said that... I'm not yet sure if hashes-plus-signature solves all our problems; but I think the criticism above is a bit too simple. |
To cycle this back to the original issues: Signatures - being a relaxation vs hashes - would potentially allow an attacker to substitute a resource that was validly signed in a different context. Examples that have been mentioned or that I can think of:
Do we have more scenarios, so that we could evaluate proposals against them? |
Have you considered using https://tools.ietf.org/html/draft-cavage-http-signatures-08 in which case you the response can specify one or more headers that must be included in the data that is signed? This seems like it solves the immediate problem and provides flexibility for hosts to use headers such as Etag to ensure the correct version is also returned. |
@adrianhopebailie: Thanks for the pointer! Skimming quickly though that document, it seems to be addressing a larger set of problems than we actually need for this use case. That said, I'd be thrilled for the signing portion of this proposal to be Someone Else's Problem™, and I know there's prior art in this area. If there's a good fit, I'm happy to use it. @mnot pointed to http://httpwg.org/specs/rfc8188.html and https://tools.ietf.org/html/draft-thomson-http-mice-02 as other documents to look into. Mark, any opinions on the HTTP Signatures doc linked above? |
Would being able to change keys help (see #8)? That was my original thinking when I first read the spec: you want to revoke old code due to a vuln, rotate the public key (and in general, good practice would be to do automatic rotation). Do other areas in code signing do any better? For example, what prevents an older version of the signed DLL from being loaded? (on a separate note, I feel like it is too early to worry about this. It feels to me under the category of "problems we would love to have".) |
@devd This issue isn't really about expiration due to a vulnerability, it's about code that's expected to be served for requests to |
@mikewest I'd say that there's been long-term interest in having some sort of signature mechanism for HTTP, but it's never been quite enough to get us a standard. It looks like that may have changed now. WRT the different proposals -- I'm not too concerned yet about how the actual bits on the wire look; we'll get there (and for that, we could start with pretty much any proposal). Personally, I'd hope that if it's needed for SRI and for what Jeffrey wants (as well as other potential use cases), we can do it just once. Use cases and requirements would be good to have more / broader discussion about; Jeffrey has given it a good start in his document, but it would be great to hear from others. We should also discuss about how comfortable people are in leveraging WebPKI for signatures; AIUI there may be some landmines there (but I'm happy to be wrong about that). Those discussions probably need a bit more visibility than on an issue in a repo that's specific to one use case. Jeffrey has activated some discussion in the IETF; let me chat with a few people and see where that's at, so we can figure out if that should live somewhere there (e.g., HTTP WG, DISPATCH), or WICG, or... (experiencing ETOOMANYHATS). |
I opened #11 to take a crack at solving this (separate issue to divert the discussion of a particular implementation from the problem in general). Posting here to get some feedback from those involved in this discussion :) |
By shifting the mechanism onto RFC9421's message signatures, we're providing developers with substantially more flexibility about the set of metadata they sign. In particular, signing the I'm going to close this out, as I think it's addressed. If there are still missing pieces, please do let me know. |
I think that signing-bodies-without-signing-their-names is likely to turn into security vulnerabilities unless everyone tightly controls which keys they use to sign which content.
The simplest example might be:
needsAuth.js
:noAuth.js
:If an origin server is "foolish" enough to sign both of those with the same key, a malicious CDN could swap them in for each other, removing authentication from pages that should insist on it.
I'm pretty sure clever security researchers will be able to construct other attacks by replacing other more benign-looking Javascript files with each other. However, if the origin server signs the name (URL and maybe request headers) of each resource with its content, then the malicious CDN loses that axis of freedom and can't run this kind of attack.
The text was updated successfully, but these errors were encountered: