DNS rebinding :* allowlist matches Host/Origin suffixes that are not ports

Open Beginner friendly
#3,463 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
84/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
security

Research direction

Start in mcp/server/transport_security.py, where TransportSecurityMiddleware matches allowed_hosts and allowed_origins, then read tests/server/test_transport_security.py. Reproduce the reported suffix cases and compare them with the existing numeric-port coverage. Done means numeric ports remain accepted while values such as wild.example:9000.evil and the matching Origin are rejected.

Written by the indexing model from the issue text.

Description

v1 v2

What happened

TransportSecurityMiddleware treats allowed_hosts / allowed_origins entries that end in :* as a prefix match: value.startswith(base + ":").

With allowed_hosts=["127.0.0.1:*"] or ["wild.example:*"], these Host values are accepted today:

  • 127.0.0.1:8080.evil
  • wild.example:9000.evil

The same pattern accepts Origin http://wild.example:9000.evil for http://wild.example:*.

Existing tests only cover a numeric port (wild.example:9000). They do not cover a suffix after the port.

What I expected

base:* should mean base plus a numeric port, not any string that starts with base:.

How to reproduce

On main @ 08a3bc8:

from mcp.server.transport_security import TransportSecurityMiddleware, TransportSecuritySettings
from starlette.requests import Request

settings = TransportSecuritySettings(
    enable_dns_rebinding_protection=True,
    allowed_hosts=["wild.example:*"],
    allowed_origins=["http://wild.example:*"],
)
mw = TransportSecurityMiddleware(settings)
req = Request({"type": "http", "method": "GET", "headers": [(b"host", b"wild.example:9000.evil")]})
# validate_request returns None (accept). I expected 421.

I can send a PR that requires the suffix after base: to be digits, plus tests for the suffix cases. Happy to do that if you want it.

Written with AI assistance. I read the matcher next to tests/server/test_transport_security.py and reproduced it locally.

Dominant language
Python
Stars
24.3k
Forks
4k
Avg merge
1d 19m
Merged PRs (30d)
29

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from modelcontextprotocol/python-sdk

All issues in modelcontextprotocol/python-sdk

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.