Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw on wrong Content-Length #1462

Merged

Conversation

greenEkatherine
Copy link
Contributor

Fixes #1412

Throwing an exception when Content-Length is set but doesn't match with actual length in request. This allows to avoid unclear hangings as described in the issue above.

Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, just left some minor comments

src/ReverseProxy/Forwarder/StreamCopier.cs Outdated Show resolved Hide resolved
src/ReverseProxy/Forwarder/StreamCopyHttpContent.cs Outdated Show resolved Hide resolved
test/ReverseProxy.Tests/Forwarder/HttpForwarderTests.cs Outdated Show resolved Hide resolved
test/ReverseProxy.Tests/Forwarder/HttpForwarderTests.cs Outdated Show resolved Hide resolved
Katya Sokolova and others added 2 commits December 17, 2021 10:50
Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
@@ -406,6 +406,7 @@ private static void RestoreUpgradeHeaders(HttpContext context, HttpRequestMessag
// but for now, out of an abundance of caution, we only do it for requests that look like gRPC.
return new StreamCopyHttpContent(
source: request.Body,
contentLength: request.Headers.ContentLength,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a scenario where we don't copy the Content-Length:

// https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3
// If a message is received with both a Transfer-Encoding and a
// Content-Length header field, the Transfer-Encoding overrides the
// Content-Length. Such a message might indicate an attempt to
// perform request smuggling (Section 9.5) or response splitting
// (Section 9.4) and ought to be handled as an error. A sender MUST
// remove the received Content-Length field prior to forwarding such
// a message downstream.
if (httpContext.Request.Headers.ContainsKey(HeaderNames.TransferEncoding)
&& httpContext.Request.Headers.ContainsKey(HeaderNames.ContentLength))
{
proxyRequest.Content?.Headers.Remove(HeaderNames.ContentLength);
}

Can StreamCopyHttpContent capture the ContentLength from its own headers on start?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered it but StreamCopyHttpContent get it before transformation (step 2 vs step 3):

// :: Step 2: Setup copy of request body (background) Client --► Proxy --► Destination
// Note that we must do this before step (3) because step (3) may also add headers to the HttpContent that we set up here.
var requestContent = SetupRequestBodyCopy(context.Request, isStreamingRequest, activityToken);
destinationRequest.Content = requestContent;
// :: Step 3: Copy request headers Client --► Proxy --► Destination
await transformer.TransformRequestAsync(context, destinationRequest, destinationPrefix);

Did I miss something?

Copy link
Member

@Tratcher Tratcher Dec 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct on the ordering, but you can capture the header at the start of SerializeToStreamAsync, you don't need it in the constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, I moved capturing out of the constructor.

@Tratcher
Copy link
Member

Looks good overall. My comments are mostly style and flow.

Katya Sokolova and others added 3 commits December 20, 2021 11:57
Katya Sokolova and others added 2 commits December 20, 2021 20:36
Co-authored-by: Chris Ross <Tratcher@Outlook.com>
@greenEkatherine greenEkatherine merged commit 5b8aeec into microsoft:main Dec 20, 2021
@Tratcher Tratcher added this to the YARP 1.1.0 milestone Dec 20, 2021
@MihaZupan MihaZupan modified the milestones: YARP 1.1.0, YARP 1.1.0-RC1 Mar 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Timeout when request body is consumed before proxying
3 participants