Subject: Benjamin Kaduk's Discuss on draft-ietf-httpbis-proxy-status-06: (with DISCUSS and COMMENT)

From: Benjamin Kaduk via Datatracker <[email-masked]>
Date: Wed, 25 Aug 2021 14:21:31 -0700

Benjamin Kaduk has entered the following ballot position for
draft-ietf-httpbis-proxy-status-06: Discuss

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-httpbis-proxy-status/

----------------------------------------------------------------------
DISCUSS:
----------------------------------------------------------------------

draft-ietf-httpbis-semantics seems to require that in order to merge a
trailer field into the header section, the field definition both
explicitly permits the merging action "and defines how trailer field
values can be safely merged."  The discussion in §2 of this document
about preserving ordering of trailer values relative to other
intermediaries seems to imply that trailer fields will be merged into
the header section (otherwise how could there be an order?), but I do not see a
specification for how to safely perform the merge operation.  Can we have
more clarity on the expected behavior in this case?

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

Thanks to Rich Salz for the secdir review, and the authors for making
the indicated changes.

I made a couple pull requests with some suggested edits at:
https://github.com/httpwg/http-extensions/pull/1618
https://github.com/httpwg/http-extensions/pull/1619

Section 2.1.3

   The "next-protocol" parameter's value indicates the ALPN protocol
   identifier [RFC7301] used by the intermediary to connect to the next
   hop.  This is only applicable when that connection was actually
   established.

   The value MUST be either an sf-token or sf-binary, representing a TLS
   Application-Layer Protocol Negotiation (ALPN) Protocol ID (see

I do know about "h2c" and Upgrade, but I think there are cases where
neither TLS nor Upgrade is used.  Is there some way to indicate, e.g.,
that HTTP/1.1 without TLS was used?  I do not believe that setting
"http/1.1" here has those semantics in the way that "h2c" does, and it
seems that there may some value in indicating whether a secure transport
was used for the next hop in a similar way to how setting "h2" or "h3"
here would do so.

   [...] If the protocol
   identifier is able to be expressed as an sf-token using ASCII
   encoding, that form MUST be used.

There seems to be some ossification risk of the sf-binary form is never
used.  I would hope that the use of structured fields mitigates that
risk, since sf-binary support is needed in the generic field decoder,
but I don't know that I would specifically rely on it.  The MUST here
prohibits greasing to be sure; maybe the benefit of consistency
outweighs the risk, though.

Section 2.3.13

TLS protocol errors are typically accompanied by a TLS alert message
being generated; would the 'alert-id' and 'alert-message' extra
parameters be applicable here (in addition to for "tls_alert_received"
down in §2.3.15)?

Section 2.3.15

      -  alert-message: an sf-token containing the applicable
         description string from the TLS Alerts registry.  See
         [RFC8446].

I don't think there's a formal restriction on what characters are
allowed in description strings in the TLS Alerts registry, so that,
e.g., one could in theory have an alert description containing
characters like ";" that are not allowed in an sf-token.  It's so
unlikely to happen in practice that I'm not actually concerned, but I
will ask if we want to formally provide some behavior to allow for such
cases.

Section 2.3.24

      -  coding: an sf-token containing the specific coding that caused
         the error.

Is it worth referencing the registry of such codings?

Section 4

[I included some suggestions for additional detail in the security
considerations in my PR, mentioned above]

It is probably worth saying something about how there is no E2E
validation of accuracy, e.g., a proxy could claim that it used a secure
h2 or h3 transport for the next hop even though it didn't actually do
so.

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 26 Aug 2021 11:37:27 +1000

Hi Ben,

Thanks for the feedback.

I've opened <https://github.com/httpwg/http-extensions/issues/1620> for the comments and will address those shortly. DISCUSS, er, discussion below.

> On 26 Aug 2021, at 7:21 am, Benjamin Kaduk via Datatracker <[email-masked]> wrote:
> 

The discussion there doesn't imply that they can be merged; it requires that a proxy insert a corresponding header value, so that the relative position can be tracked. For example, if a proxy receives a response with the header:

  Proxy-Status: firstProxy

and it wants to reserve itself the right to insert a trailer, it will emit this header:

  Proxy-Status: firstProxy, secondProxy

... so that it has the option to insert this trailer:

  Proxy-Status: secondProxy

... allowing clients to make sense of when that happened relative to other things.

As per http-core, the only time a proxy can promote the contents of a trailer field into a header field is when the field's specification explicitly allows that. This specification does not. 
 
I think it would be reasonable to explicitly point that out, although it's not strictly necessary.

Alternatively, we could specify that a trailer value can be promoted into the header field by replacing the last instance of a member with the same (character-by-character) identifier.

Do folks have a preference? 

Personally, I suspect that promotion would be somewhat rarely used, but not useless; e.g., when a response with a trailer in it is cached, the proxy would have an easy opportunity to promote the trailer into a header for future consumers. That said, I'm leaning a bit towards just explicitly prohibiting it, as I'm always nervous about making substantial changes at the last minute...

Cheers,

--
Mark Nottingham   https://www.mnot.net/

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 26 Aug 2021 00:12:18 -0700

Hi Mark,

I'm just about to head to sleep, so apologies if this is incoherent.

And perhaps I should have stuck with what I had originally put in my review
notes, which was roughly "this text is confusing and I am not confident I
understand what it's trying to say"...

> The discussion there doesn't imply that they can be merged; it requires that a proxy insert a corresponding header value, so that the relative position can be tracked. For example, if a proxy recei…

Pedantically, I don't think the current text actually makes requirements on
inserting values.  I could be missing some subtlety (with structured fields
terminology?), but I think the current text boils down to "it is a protocol
error for the Proxy-Status field to appear in the trailers of a response if
it does not also appear in the headers of that response"

But even if we take it as intended, that any list member in the trailers
has to have a corresponding list member in the headers, it does seem that
the requirement being imposed is to allow a logical merge, even if it is
not formally a merge at the protocol level.

> ... allowing clients to make sense of when that happened relative to other things.

Well, yes and no.  "When" usually implies time, but we don't have any
absolute time information, only information about location in the proxy
chain.

So the core goal/requirement here seems to be to allow the intermediary
that added the trailer list entry to be ordered with respect to the
intermediaries that added header list entries, in effect tightly binding
each piece of information in the trailer field to a specific corresponding
piece of information in the header field.  To me, that is logically merging
the respective pieces of information, and it's clear that the information
produced later (in absolute time) would override the information produced
earlier.

> Do folks have a preference? 

I don't particularly have a preference.  It seems like a clear candidate
for the sort of thing where merging is possible and makes sense, but your
instincts about last-minute substantial changes are not unfounded.
I do think that the current text is unclear about what should happen and,
to a lesser extent, why.

> Personally, I suspect that promotion would be somewhat rarely used, but not useless; e.g., when a response with a trailer in it is cached, the proxy would have an easy opportunity to promote the tr…

(This cached response case is exactly what I had in mind when thinking that
merging would be natural.)

-Ben

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 26 Aug 2021 17:19:53 +1000

Hello (again) Ben.

> On 26 Aug 2021, at 5:12 pm, Benjamin Kaduk <[email-masked]> wrote:
> 

I don't think that's a correct reading of the current text, but I grant that a pedantic reading is likely to find flaws, due to the nature of... well, what we do here.

> not formally a merge at the protocol level.

Indeed.

> absolute time information, only information about location in the proxy

Hence, 'relative'.

> the respective pieces of information,

Yes. What's at question here is whether a recipient is allowed to reflect that merge into a forwarded response by rewriting its header and trailer fields.

> and it's clear that the information

Whoa. That is not at all clear to me. Can you explain how you arrived at that?

> merging would be natural.)

Nod. I might create a PR describing the merge process, so we can look at it.

Cheers and sleep well,

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 26 Aug 2021 17:47:30 +1000

> On 26 Aug 2021, at 5:19 pm, Mark Nottingham <[email-masked]> wrote:
> 

See:
  https://github.com/httpwg/http-extensions/pull/1621

Cheers,

---

From: Benjamin Kaduk <[email-masked]>
Date: Tue, 31 Aug 2021 14:55:02 -0700

> Whoa. That is not at all clear to me. Can you explain how you arrived at that?

Oops, the "if there is conflict between the two" failed to make it out of
my brain.

One risk in defining/how to define a merge algorithm is the risk of
conflict in a non-obvious way (across parameters, I guess).

There seems to be some amount of freedom in how to handle non-conflicting
parameters, with options including "remove from the header list entry any
parameters that appear in the corresponding trailer list entry, then append
the parameters from the trailer list entry to the header list entry" and
"drop the header list entry entirely, replacing it with the contents of the
trailer list entry".  The latter would make the behavior and semantics
pretty well-defined and make it easy for a proxy to know how to "change its
mind" about the field value, at the cost of requiring it to remember things
it sent in the header list entry that might need to remain in the
post-merge entry.  The former makes things easy for the proxy inserting the
trailer field entry at the cost of a more complicated or risky merge
algorithm at the recipient.  Your PR (maybe not a strawman anymore,
https://github.com/httpwg/http-extensions/pull/1621/files) seems to match
what I call "the latter option", and it seems pretty good to me provided
that the cost of retaining the bits from the header field for potential
re-use in the trailer field is tolerable.  (I'm not terribly well
calibrated on the relative costs here and what is deemed acceptable in
practice, though.)

-Ben