- From: Justin Richer <jricher@mit.edu>
- Date: Tue, 22 Nov 2022 03:06:46 +0000
- To: Kyle Rose <krose@krose.org>
- CC: HTTP Working Group <ietf-http-wg@w3.org>
- Message-ID: <33CBA088-CA33-4271-8033-69A58EEBD4A5@mit.edu>
Hi Kyle, answers inline, with some of the excess trimmed for clarity. * "The context MUST be consistent across all components." I'm not sure what it means for a context to be consistent across components. From looking at 7.4.3, it seems like the context is defined as whatever information the 2+ parties to a message share and agree to regard as in-bounds input to a message signature. I'm finding it hard to explain the difficulty I'm having interpreting this statement, so maybe one way to think about it is by asking the question, "What is an example of a context that is *inconsistent* across components?" The context is actually just the context of the party either creating or verifying the signature, not something that they agree on. Let’s say, as a strawman example, the verifier gets a signature that includes “@query” and “@query-param” in the signature, for some weird reason. Obviously, these values should be derived from the same data source. However, there are some web app frameworks that do weird things like override values in a pre-parsed query parameters map available to the application. In this case, if a naive developer signs a @query-param that ends up coming from the app framework instead of the request, or gets overridden by it, then the verifier is using two different contexts for these components. Ultimately, what this text means is that your context needs to be consistent and well-defined when you’re pulling your component values out, and you shouldn’t change your context in the middle of processing a signature. Makes sense. I would then explicitly define what "context" and "consistent" mean here, maybe replacing the entire second paragraph with something like: The context for a signed HTTP message comprises the set of components employed in creating and subsequently verifying an HTTP message signature. For signatures to be verifiable by receivers, this context MUST be identical across all parties to the signature (signer and all verifiers). A context that is shared in such a way shall be regarded as "consistent". Two notes, however: * You might instead choose to define "context" in a similar way in the glossary above. * "Consistent" is not used anywhere subsequently in the document, so you might instead just drop that definition. Makes sense, we can add a definition for the message context as used in the draft. * "Within a single list of covered components, each component identifier MUST occur only once." Is there a good reason for this? I mean, it's pointless extra computation, but restricting it means adding complexity around eliminating duplicate identifiers that require more than a simple string compare (given the reordering of parameters). There’s no additional computation needed here, really, but it helps define the properties of a well-defined signature. What would be the use case of allowing a duplicate identifier? You’d get the same value in the signature twice, since each component identifier needs to resolve to exactly one value. I think I'm not getting my point across adequately. Here are the two options: 1. (As stated in the draft) Prohibit multiple instances of a component identifier. This means implementations must add checks that a component identifier isn't included in a signature multiple times, which would involve prohibiting the inclusion of both `"foo";bar;baz` and `"foo";baz;bar` but allowing `"foo";bar;baz` and `"foo";bar,quux`. 2. (My proposal) Allow multiple instances of the same component identifier. All this does is make the signature computation and verification take slightly longer if a duplicate identifier is included, and allowing it means no complex de-duplication checks. #1 seems like a pointless guardrail in a protocol that otherwise delegates most of the responsibility to users to do the right thing when choosing a signature schema. This is a definition of a well-formed signature set. While I understand the point you’re raising here, I don’t see what value there is in relaxing this part of the definition. 2.4. Request-Response Signature Binding: * If a request lacks a Content-Digest, there appears to be no way to cryptographically tie a response to the body of an unsigned request. I can definitely see use cases for unsigned requests with signed responses. I do not understand the point here. You can add anything from the request to the response signature using “req” flags. I mean (unless I missed something) there's no way to refer to the content body of a request, only to headers and request metadata. You can't refer to (e.g.) @req.body to include the entire body in the signed data. If there's a header that cryptographically depends on the entire request body (e.g., req.content-digest) you can refer to that. (I'll note in doing so you're also relying on the stack having verified that digest against the message content before processing the message, which may or may not be fine; I don't know what the normative language in the HTTP ecosystem for treatment of Content-Digest is.) There’s also no way to sign the body of the target message, either — that’s offloaded to the Digest draft and is not part of the signature processing. This was a deliberate decision to limit the signature processing since there are a lot of strange circumstances with dealing with the content, which you can see in the digest draft in great detail. So yes: If the request includes the content-digest, then the “req” parameter can be used to point at that using “content-digest”;req as the identifier. Note that this can be used whether or not the request contains a signature, though, so an unsigned request can still be referred to in the response. If the request doesn’t include the content-digest or repr-digest or digest, then you are right in that you cannot sign anything about the request body in a response, but you can’t sign the body of responses for the same reasons.. If an application needs to guarantee this kind of processing, then the application can make sure that the sender always sends some kind of digest with the message so that it’s available in the response. — Justin
Received on Tuesday, 22 November 2022 03:07:15 UTC