Skip to content

Reject non-loopback Host headers for loopback web servers#5289

Open
petrmarinec wants to merge 1 commit intogoogle:mainfrom
petrmarinec:fix-local-host-dns-rebinding
Open

Reject non-loopback Host headers for loopback web servers#5289
petrmarinec wants to merge 1 commit intogoogle:mainfrom
petrmarinec:fix-local-host-dns-rebinding

Conversation

@petrmarinec
Copy link
Copy Markdown

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:

When ADK is bound to loopback, such as the default 127.0.0.1, the web server currently relies on an origin check that derives the request origin from the incoming Host header. A DNS-rebound request can use the same non-loopback hostname in both Host and Origin, causing the request to be treated as same-origin.

Solution:

This change adds a loopback Host check for loopback-bound ADK servers. When enabled, requests must use a loopback Host header such as localhost, 127.0.0.1, or ::1; non-loopback hostnames are rejected before the existing origin check runs. The check is enabled only when the server is configured to bind to a loopback host, preserving behavior for explicitly non-loopback binds such as 0.0.0.0.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Passed pytest results:

  • PYTHONPATH=src python -m pytest tests/unittests/cli/test_fast_api.py -k "builder_save_rejects_cross_origin_post or builder_save_rejects_dns_rebound_host or builder_save_allows_same_origin_post or builder_get_allows_cross_origin_get or independent_telemetry_context" -vv on Windows: 5 passed
  • docker run --rm -v "${PWD}:/workspace" -w /workspace python:3.11-bookworm bash -lc "python -m pip install --upgrade pip >/tmp/pip-upgrade.log && python -m pip install -e '.[test]' >/tmp/pip-install.log && PYTHONPATH=src python -m pytest tests/unittests/cli/test_fast_api.py -vv": 63 passed
  • python -m pyink --check src/google/adk/cli/adk_web_server.py src/google/adk/cli/fast_api.py tests/unittests/cli/test_fast_api.py: unchanged

Manual End-to-End (E2E) Tests:

Manual validation was performed with an in-process FastAPI test client:

  • clean origin/main: a request with Host: rebind.attacker.example:8000 and matching Origin: http://rebind.attacker.example:8000 returned 200 true
  • this branch: the same request returned 403 Forbidden: host not allowed
  • this branch: Host: rebind.attacker.example:8000 without an Origin header also returned 403 Forbidden: host not allowed
  • this branch: Host: localhost returned 200 for the same local test client setup

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

The full repository unit test suite was not run locally. The relevant CLI web server unit test file passes in Linux Docker.

@adk-bot adk-bot added the web [Component] This issue will be transferred to adk-web label Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

web [Component] This issue will be transferred to adk-web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reject non-loopback Host headers for loopback ADK web servers

2 participants