- From: Watson Ladd <watsonbladd@gmail.com>
- Date: Wed, 8 Feb 2023 23:10:02 -0800
- To: Justin Richer <jricher@mit.edu>
- Cc: Dennis Jackson <ietf@dennis-jackson.uk>, HTTP Working Group <ietf-http-wg@w3.org>
On Wed, Feb 8, 2023 at 12:35 PM Justin Richer <jricher@mit.edu> wrote: ><chop> > > Furthermore, I think there’s an alternative approach which could fit the work of an extension: have a new derived component with the behavior listed in the proposal below. For argument sake let’s call this “@signature” and we can even have it take a parameter to select which signature of the target message is being called upon. The component value of this derived component would be the signature base of the target signature, re-generated and then encoded, perhaps as an sf-string item to escape newlines and quotes and other potentially problematic items, or even enforce use of the “bs” flag that would give us the encoding properties we’re after. That way there’s no special casing of the field, it’s a production rule of the derived component definition that’s either supported or not by the implementation — and any derived components that aren’t recognized cause an error and cessation of processing of the signature base. Annabelle and I discussed doing exactly this a while ago but rejected it because of the additional complexity it adds on top of just signing a header like any other header. I'm not sure that @signature or the original proposal actually work for a different reason: How does the sender HTTP request knows which header fields affect the contents of the response and need to be signed? E.g. if content-type isn't signed in the request, but the server wants to associate response with request and the response varies with content type, we've got an issue. The safe thing would be to reject, but I don't know how practical that is. So I think the server needs to sign exactly the fields that affect its processing of the response extracting them one by one. What if we explicitly added a Commitment option that works like a signature but just takes a hash for use in response signing? While this is impacted by my observation above, it it is just signing another header and is easily generated by the same code as produces a signature: instead of signing, hash. Might be a good chunk of text though. > > My proposal for addressing this issue is to take the following actions, none of which fundamentally change the existing draft’s processing: > > - Update the examples and advice that talk about signing another signature value and instead have the examples sign more specific components instead of the signature (for the request-response binding) or additional rationale for the transitivity of the trust (in the reverse proxy example). > - Add a security consideration section that details this specific sig-over-sig attack, using Dennis’s well-reasoned example below. > - Expand the signature collision section with discussion of the kind of key-collision that makes this attack viable, and which has been studied in the referenced papers. > - Target the expanded “@signature” derived component, expanded above, as an extension to this draft with its own deeper discussion. > - Bring this issue to the OpenID Foundation’s FAPI working group, which is where the original non-repudiation linking use case and requirement came from that lead to the addition of this function. I believe that community can offer some important insight into how this could be addressed. I'm not familiar with FAPI, but I think this might be worth reaching out to academics/research groups capable of providing such analysis. Sincerely, Watson Ladd -- Astra mortemque praestare gradatim
Received on Thursday, 9 February 2023 07:10:26 UTC