fix: guard reads in the dev server against DNS rebinding - #744
Open
prasanna8585 wants to merge 2 commits into
Open
fix: guard reads in the dev server against DNS rebinding#744prasanna8585 wants to merge 2 commits into
prasanna8585 wants to merge 2 commits into
Conversation
The dev server (adk web / api_server) applied CORS only when an operator explicitly configured --allow_origins, and had no Host-header validation anywhere. A page reached by rebinding an attacker-controlled hostname to 127.0.0.1 is same-origin as far as the browser is concerned, so it omits Origin -- meaning every read endpoint (GET /list-apps, /version, and others) was reachable from any external page a developer running the dev server happened to visit, with no explicit configuration required to be vulnerable. Adds isDnsRebindingRequest, checking the Host header against the server's actual bind host (not a client-suppliable header) and any operator-configured --allow_origins host. Applied as the very first middleware, before any route including /health and /version, and on every method (not just state-changing ones) since Origin cannot be relied on for a same-origin-looking rebound request. Matches the fix adk-python shipped the same day for the identical bug in the identical framework. Dynamically confirmed with node:http's raw client (fetch() silently rewrites Host to match the real connection target for any request it dispatches, so it cannot be used to reproduce what a rebound page's browser actually sends on the wire). Adds three regression tests: accepts a request whose Host names the loopback bind, rejects a GET whose Host does not, and rejects a read endpoint with no Origin header at all -- the exact shape of a DNS-rebound request. Full adk_api_server_test.ts suite (70 tests) passes.
kalenkevich
reviewed
Aug 14, 2026
Per review: isLoopbackAddress, getAllowedRequestHosts, and isDnsRebindingRequest now live in dns_rebinding_guard.ts instead of adk_api_server.ts.
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.
The dev server (
adk web/api_server) applied CORS only when an operator explicitly configured--allow_origins, and had no Host-header validation anywhere. A page reached by rebinding an attacker-controlled hostname to127.0.0.1is same-origin as far as the browser is concerned, so it omitsOrigin-- meaning every read endpoint (GET /list-apps,/version, and others) was reachable from any external page a developer running the dev server happened to visit, with no explicit configuration required to be vulnerable.This matches the fix adk-python shipped the same day (
2cf4fd1) for the identical bug in the identical framework.Adds
isDnsRebindingRequest, checking theHostheader against the server's actual bind host (not a client-suppliable header) and any operator-configured--allow_originshost. Applied as the very first middleware, before any route including/healthand/version, and on every method (not just state-changing ones) sinceOrigincannot be relied on for a same-origin-looking rebound request.Dynamically confirmed with
node:http's raw client --fetch()silently rewritesHostto match the real connection target for any request it dispatches, so it can't be used to reproduce what a rebound page's browser actually sends on the wire. Added three regression tests: accepts a request whose Host names the loopback bind, rejects a GET whose Host does not, and rejects a read endpoint with no Origin header at all (the exact shape of a DNS-rebound request). Fulladk_api_server_test.tssuite (70 tests) passes.