jsr369-experts@servlet-spec.java.net

[jsr369-experts] Re: [servlet-spec users] Re: Trailer header implementation

From: Stuart Douglas <sdouglas_at_redhat.com>
Date: Wed, 10 May 2017 14:46:46 +1000

On Tue, May 9, 2017 at 7:30 AM, Shing Wai Chan
<shing.wai.chan_at_oracle.com> wrote:
> MM> I'll try one more time. Headers in the trailer part of the message are
> just normal
> MM> headers, same as headers from the start of the message and there is
> nothing in the
> MM> RFC which requires the http implementation to provide trailers as if
> they are
> MM> something special and separate from these other headers. I spoke with
> our http
> MM> component lead developer and he agrees with this assessment. To avoid
> the apparent
> MM> confusion on the application side the Trailer header is provided to
> inform the
> MM> recipient of the trailer headers to expect. We could use getTrailers()
> as a convenience
> MM> method where we return the fields specified in the trailer header, but
> then we start
> MM> exposing the RFC in our API which as we agreed in another thread we
> should no do.
> MM> For getTrailers() to return everything form the trailer we need the http
> component
> MM> to also provide that support which I do not think we should be imposing
> in the Servlet
> MM> Specification.
>
> I have discussed this with Ed. We are both ok to use existing request header
> API
> for request trailer. And no new API is added for request trailer.
>
> In this case, we will only add API for response trailer.
>
> Is this ok for other EG?
> Please let us know.

This is -1 from me as I think there are security implications, in that
servlet applications may see 'headers' in the request map that were
not processed as such by intermediaries (because they are actually
trailers). This is a similar issue to HTTP Request Smuggling, where
the servlet application sees a different view of the request than an
intermediate proxy.

e.g. consider a setup where a proxy performs authentication, and then
forwards the authenticated user information in a header to the backend
server. This backend server then calls ServletRequest.getHeader() to
determine the authenticated user. A malicious client could send this
authenticated user information in a trailer instead of a header, which
could bypass security measures in the proxy.

Another example would be proxies that append an X-Forwarded-For
header. A malicious client could potentially send this as a trailer,
and potentially use this to spoof the remote address that is seen by
the Servlet application.

I think this is a really bad idea, that would bite us later. Given
that the majority of applications do not use trailers I would prefer
we just ignore the issue and leave support up to container specific
API's (i.e. the current state of affairs) than go down this route.

Stuart


>
> Shing Wai Chan
>
>
> On May 8, 2017, at 2:02 PM, Martin Mulholland <mmulholl_at_us.ibm.com> wrote:
>
>
> Shing Wai Chan <shing.wai.chan_at_oracle.com> wrote on 05/08/2017 03:48:00 PM:
>
>> From: Shing Wai Chan <shing.wai.chan_at_oracle.com>
>> To: jsr369-experts_at_servlet-spec.java.net
>> Date: 05/08/2017 03:48 PM
>> Subject: [servlet-spec users] [jsr369-experts] Trailer header
>> implementation
>>
>> Let us discuss more on Section 3 in my previus email thread.
>>
>> Section 3: get trailer
>> MM> For an inbound trailer Section 4.1.2 of RFC2370 says:
>> MM> <quote>
>> MM> When a chunked message containing a non-empty trailer is
>> received,
>> MM> the recipient MAY process the fields (aside from those forbidden
>> MM> above) as if they were appended to the message's header section.
>> MM> </quote>
>> MM> So in addition to getTrailers() we should make the trailer headers
>> MM> avaiable through the getHeader() api's and automatically add them when
>> MM> they become available (all inbound data is read).
>> MM> But this leads me to a concern that the RFC is a specification of how
>> MM> the transport layer should behave and it s not clear to me how much of
>> MM> this transport function should be exposed in the Servlet
>> Specification.
>> MM> In the Servlet Spec we should not be making assumptions about how the
>> MM> transport layer works in which case we should not have a getTrailers()
>> MM> API but instead we just expose the headers using existing api's once
>> all
>> MM> the data is read. That way we work whether or not the transport layer
>> MM> exposes the trailer headers or not.
>>
>> SW> On April 6, 2017, I proposed (in (a) StandardHeader option [1]) to use
>> SW> the standard header APIs as one of the option to retrieve trailer
>> fields.
>> SW> This option was rejected in [2] and [3] as follows:
>> GW> with regards to request trailers, the key decision is when they
>> are
>> GW> available, specially with async. Does the application have to read
>> GW> content
>> GW> to -1 or onAllDataRead before the trailers are available? Ithink
>> yes.
>> GW> Then it does not make much sense to make them available via the
>> normal
>> GW> header API and I think they need their own API.
>>
>> SD> I don't think this is a good approach. The trailers will not be
>> SD> available immediately, so this will basically result in the
>> headers
>> SD> changing after the request has been read. I think it could be very
>> SD> confusing to the developer.
>>
>> SW> Since the trailer fields are processed "as if they were appended to
>> the
>> SW> message's header section."
>> SW> Should trailer fields be available to get header API's, too?
>>
>> MT> I think not. I agree that having the return values for the standard
>> MT> header API change depending on whether the request is fully read or
>> not
>> MT> is very likely to cause confusion. So +1 to GW and SD comments above.
>>
>> MM> I disagree, if the app reads the trailer header it knows which headers
>> to
>> MM> re-read after the inbound data is fully read. Adding getTrailers()
>> MM> is imposing a level of support from the transport layer which to me is
>> MM> not appropriate.
>>
>> SW> Given section 4.1.2 of RFC 2370, if a servlet container, prior to
>> Servlet 4.0,
>> SW> returns the trailer through #getHeader after inputStream returns -1,
>> SW>we should not explicitly disallow it in Servlet 4.0.
>>
>> SW> In Servlet 4.0, we will return trailer fields through the new API
>> SW> #getTrailerFields().
>>
>
> I'll try one more time. Headers in the trailer part of the message are just
> normal
> headers, same as headers from the start of the message and there is nothing
> in the
> RFC which requires the http implementation to provide trailers as if they
> are
> something special and separate from these other headers. I spoke with our
> http
> component lead developer and he agrees with this assessment. To avoid the
> apparent
> confusion on the application side the Trailer header is provided to inform
> the
> recipient of the trailer headers to expect. We could use getTrailers() as a
> convenience
> method where we return the fields specified in the trailer header, but then
> we start
> exposing the RFC in our API which as we agreed in another thread we should
> no do.
> For getTrailers() to return everything form the trailer we need the http
> component
> to also provide that support which I do not think we should be imposing in
> the Servlet
> Specification.
>
> Thanks,
> Martin.
>
>
>
>
>