Repository navigation
Harden HTTP streaming proxy surface - #436
Merged
Laveesh Rohra (larohra) merged 13 commits intoMay 13, 2026
Merged
Laveesh Rohra (larohra) merged 13 commits into
Laveesh Rohra (larohra) merged 13 commits into
Conversation
added 12 commits
May 13, 2026 09:27
…to swarm/9e1d1fce/integration
There was a problem hiding this comment.
Pull request overview
This PR hardens the internal HTTP streaming proxy used when enableHttpStream is enabled by binding it to loopback and rejecting malformed proxy traffic.
Changes:
- Binds the HTTP proxy to a concrete loopback address and serializes the advertised
HttpUriaccordingly. - Adds validation for malformed or duplicate invocation ID headers.
- Adds tests for proxy behavior, streaming invocation handling, and capability negotiation.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/http/httpProxy.ts |
Implements loopback binding, loopback URI serialization, invocation ID validation, and async port probing. |
test/http/httpProxy.test.ts |
Adds proxy behavior coverage for loopback binding, malformed requests, buffering, responses, cookies, and port fallback. |
test/InvocationModel.test.ts |
Adds streamed HTTP invocation coverage using the proxy request/response path. |
test/ProgrammingModel.test.ts |
Adds capability negotiation coverage for advertised streaming HttpUri and setup locking. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Swapnil Nagar (swapnil-nagar)
requested changes
May 13, 2026
Swapnil Nagar (swapnil-nagar)
left a comment
Contributor
There was a problem hiding this comment.
Update the package version to 4.15.0
Laveesh Rohra (larohra)
merged commit May 13, 2026
18b57a5
into
Azure:larohra/harden-auth
7 of 13 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
src/http/httpProxy.tsis the internal HTTP streaming bridge behindapp.setup({ enableHttpStream: true }).server.listen()with no host, so Node binds the proxy on a wildcard interface even though the worker advertiseshttp://localhost:<port>/back to the host.azure-functions-host,src/WebJobs.Script.Grpc/Channel/WorkerChannel.csonly parsesHttpUriwithnew Uri(httpUri)and uses it for proxying, whilesrc/WebJobs.Script/Http/DefaultHttpProxyService.csoverwritesx-ms-invocation-idbefore forwarding.Assessment
HttpUrias a customer contract. The real gap is the worker’s wildcard listener plus permissive handling of direct requests from anything that can reach the sandbox/pod namespace. Even if the host never leaks the URI, the wildcard bind (and the fixed 55000-55025 fallback range) still creates discoverable local surface.localhosttoday, and it accepts any absoluteHttpUri. No for full channel authentication: the host does not send any shared secret today, andWorkerChannelstarts HTTP forwarding before the worker receives the gRPC invocation, so the library cannot repo-only pre-whitelist expected invocation IDs.server.listen()behavior with no evidence that wildcard binding was an intentional security posture. PR Add port validation checks for HTTP streaming #315 (“Add port validation checks for HTTP streaming”) later fixed Windows/VNET port-0 reliability but still returnedlocalhost, which reinforces that loopback was the intended contract and wildcard binding was an implementation gap.HttpUrias an opaque absolute URI string, so returning127.0.0.1or[::1]is not a customer API break. The real risks are IPv4/IPv6 family selection, URI formatting, and port-0 retry behavior.npm ci(357 passing), but this repo still lacks direct coverage forsrc/http/httpProxy.tsandProgrammingModel.getCapabilities/streamed invocation setup. The host repo does have contract-oriented coverage for correlation-header override (DefaultHttpProxyServiceTests), forwarded-header behavior (ScriptInvocationRequestTransformerTests), and theHttpUriproxying path (ScriptInvocationContextExtensionsTests).Implementation direction
src/http/httpProxy.tsto bind one concrete loopback address, use it consistently for the listener and port-probe/rebind path, and fail malformed proxy requests fast.HttpUrias an internal absolute URI capability and keepx-ms-invocation-idcorrelation semantics; do not add new repo-only auth signals or public API changes.ProgrammingModeland streamed invocation behavior so the hardened worker stays compatible with the current host contract and avoids address-family regressions.Non-goal / follow-up
azure-functions-host+ library handshake change rather than a library-only patch.