Skip to content

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

Open
petrmarinec wants to merge 2 commits into
google:mainfrom
petrmarinec:fix-local-host-dns-rebinding
Open

Reject non-loopback Host headers for loopback web servers#5289
petrmarinec wants to merge 2 commits into
google:mainfrom
petrmarinec:fix-local-host-dns-rebinding

Conversation

@petrmarinec
Copy link
Copy Markdown
Contributor

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
@rohityan rohityan self-assigned this Apr 13, 2026
@rohityan rohityan added the request clarification [Status] The maintainer need clarification or more information from the author label Apr 13, 2026
@rohityan
Copy link
Copy Markdown
Collaborator

rohityan commented Apr 13, 2026

Hi @petrmarinec , Thank you for your contribution! We appreciate you taking the time to submit this pull request. Please fix formatting errors by running autoformat.sh and fix the failing unit tests.

@petrmarinec
Copy link
Copy Markdown
Contributor Author

Hi, quick follow-up here: the formatting/unit-test issues mentioned earlier have been addressed on the current PR head, and the PR checks are green now. Happy to provide any additional detail if that would help with review.

@rohityan rohityan added needs review [Status] The PR/issue is awaiting review from the maintainer and removed request clarification [Status] The maintainer need clarification or more information from the author labels May 12, 2026
@rohityan rohityan requested a review from xuanyang15 May 12, 2026 03:12
@rohityan
Copy link
Copy Markdown
Collaborator

Hi @xuanyang15 , can you please review this.

@xuanyang15 xuanyang15 self-assigned this May 12, 2026
@xuanyang15
Copy link
Copy Markdown
Collaborator

Hi @petrmarinec Thanks for creating this PR! Could you please help rebase the PR to 2.0 (i.e. the latest main branch)?

@wyf7107 Could you please help review after the rebase?

@xuanyang15 xuanyang15 assigned wyf7107 and unassigned xuanyang15 May 21, 2026
@petrmarinec petrmarinec force-pushed the fix-local-host-dns-rebinding branch from a15646d to dbfe472 Compare May 21, 2026 21:45
@petrmarinec
Copy link
Copy Markdown
Contributor Author

Hi @petrmarinec Thanks for creating this PR! Could you please help rebase the PR to 2.0 (i.e. the latest main branch)?

@wyf7107 Could you please help review after the rebase?

Hi, rebased to the latest main and pushed the updated branch.

I also reran the targeted validation locally after the rebase:

  • the DNS-rebinding / loopback Host-header checks pass
  • the trigger-routes regression test passes as well

Happy to provide anything else that would help with review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review [Status] The PR/issue is awaiting review from the maintainer 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

5 participants