Skip to content

Harden HTTP proxy header handling#440

Open
TsuyoshiUshio wants to merge 4 commits into
v4.xfrom
fix/msrc-http-proxy-user-header-handling
Open

Harden HTTP proxy header handling#440
TsuyoshiUshio wants to merge 4 commits into
v4.xfrom
fix/msrc-http-proxy-user-header-handling

Conversation

@TsuyoshiUshio
Copy link
Copy Markdown
Contributor

Summary

  • block hop-by-hop and framing response headers from the HTTP proxy response path
  • handle invalid x-ms-client-principal payloads without failing the invocation
  • add focused tests for proxy header filtering and invalid client principal JSON

Notes

F4 (ensureErrorType object serialization) is intentionally not changed in this PR. That area needs a separate design discussion because the safer fix likely requires sanitizer behavior aligned with azure-functions-host and azure-functions-nodejs-worker, not just using an object's message property.

Validation

  • npm test (375 passed)
  • npm run lint

Block hop-by-hop response headers from being forwarded through the HTTP proxy and handle invalid x-ms-client-principal payloads without failing the invocation.

Co-authored-by: Dobby <dobby@microsoft.com>
@TsuyoshiUshio TsuyoshiUshio requested a review from a team as a code owner May 19, 2026 20:39
Comment thread src/http/extractHttpUserFromHeaders.ts
Comment thread src/http/httpProxy.ts
proxyRes.setHeader(key, val);
if (isAllowedProxyResponseHeader(key)) {
proxyRes.setHeader(key, val);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Content-Length is an end-to-end header, and customers may set it intentionally for HEAD/304/206 responses, downloads, or other scenarios where clients rely on it. Dropping it could change behavior for existing apps.

Can you check RFC Compliant docs if we can preseves 'content-length'.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point. \Content-Length\ is an end-to-end header, and dropping it may have compatibility impact for HEAD/304/206/download scenarios. I am leaving this thread open for discussion rather than changing it blindly. My original concern was mismatched framing when proxying streamed bodies; we should decide whether preserving it is preferred or whether only conflicting cases should be filtered.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So what's your recommendation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My recommendation is to preserve Content-Length and remove it from the blocked header list.

Content-Length is end-to-end response metadata, not a hop-by-hop header, and removing other hop-by-hop headers does not change the response body bytes. Dropping it could break existing apps that intentionally set it, especially for HEAD/304/206/download scenarios.

The original concern was about forwarding connection/framing controls through this proxy. This code copies user response headers to Node.js ServerResponse, then writes the response body through proxyRes.write(...). If we forward headers like Connection, TE, Trailer, Transfer-Encoding, or Upgrade, those headers can describe connection-specific behavior or wire framing that should be owned by the proxy/Node response layer instead.

To address that without treating Content-Length as hop-by-hop, I updated the implementation to:

  • allow content-length;
  • keep blocking the standard hop-by-hop headers;
  • also strip any header names listed by the Connection header, because Connection: x-private-hop marks x-private-hop as connection-specific and a proxy should not forward it.

I am not validating Content-Length against the streamed body here, because that would require buffering/counting the stream and would weaken the streaming path. If a user sets an incorrect Content-Length, that is a response correctness issue separate from this hop-by-hop proxy hardening.

Allow Content-Length through the HTTP proxy while continuing to block hop-by-hop headers. Also strip response headers named by the Connection header so connection-specific fields do not cross the proxy boundary.

Co-authored-by: Dobby <dobby@microsoft.com>
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.

2 participants