Review of draft-ietf-httpbis-message-signatures-13

# Review of draft-ietf-httpbis-message-signatures-13

I like the mechanism this draft describes and intend to make use of it to
enable API gateways with end-to-end authentication. I'm glad this evolved
beyond the initial focus on requests from ~4 years ago: at the time I was
looking at technologies like OSCORE, and so when I found
draft-rundgren-signed-http-requests I was immediately intrigued but
wondered why it was incomplete in a fairly obvious way. I'm glad you guys
thought so, too. :-)

I should note that I have followed none of the subsequent discussion or
development of the draft since then, so apologies in advance if I reopen
issues that have been closed via WG consensus.

2. HTTP Message Components:

* "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?"

* "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).

2.1. HTTP Fields:

* "Note that some HTTP fields, such as Set-Cookie [COOKIE], do not follow a
syntax that allows for combination of field values in this manner such that
the combined output is unambiguous from multiple inputs. However, the
canonicalized component value is never parsed by the message signature
process, merely used as part of the signature base in Section 2.5." While
the canonicalized value is never parsed, it is critical that it be 1:1 with
semantically distinct original values. That is, wherever two bit-distinct
input representations are considered equivalent, the canonicalized values
must be identical; *AND* the inverse, i.e., two input representations *not*
considered equivalent must be transformed by canonicalization into
bit-distinct values.¹ The reason for being precise here is that it must not
be possible for two semantically-distinct sequences of Set-Cookie fields to
be transformed by canonicalization into the same value, or a signature may
be regarded as valid for an unintended message. If that is within the
bounds of acceptable ambiguity, the safety or risks of doing so within this
domain must be explained. (I can't tell whether the discussion in section
7.5.6 is sufficient to cover this.)

¹Another way of saying this is that it is fine for a canonicalization
transform to lose information from the original representation so long as
that information is not semantically relevant: removal of all semantically
irrelevant information might be considered a core characteristic of a
canonicalization transform. I am close to arguing that determining what
should and should not be semantically relevant to an HTTP stack (that is,
where the line between semantic and merely syntactic differences lies) is
the most difficult problem posed by this draft, and is properly a problem
for the entire HTTP ecosystem that deserves its own treatment. However, I
recognize that the draft is intentionally leaving identification of such
potential ambiguities up to individual users of this scheme while providing
tools to disambiguate in such cases, and I regard that as a reasonable
approach.

* The X-Empty-Header canonicalization example is particularly confusing. I
recommend changing the way you represent the values in this example (e.g.,
showing the encoding in octets) to make clear the actual transformation. In
general, something like the output of hexdump might be a better way to
encode example canonicalized values in documentation such as this, even if
only in an appendix. For example:

```
00000000  61 3d 31 2c 20 20 20 20  62 3d 32 3b 78 3d 31 3b  |a=1,
 b=2;x=1;|
00000010  79 3d 32 2c 20 20 20 63  3d 28 61 20 20 20 62 20  |y=2,   c=(a
b |
00000020  20 20 63 29                                       |  c)|
```

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.

5.1. The Accept-Signature Field:

* "The requested signature..." should probably be "The signature request",
as the request for a signature (rather than the signature) is the thing the
client is indicating.

7. Security considerations:

* This section is incredibly thorough and well-written, and is a credit to
the authors and contributors.

Received on Tuesday, 15 November 2022 01:29:54 UTC