Skip to content

Commit b9f0188

Browse files
docs: add DNS rebinding protection guide
Adds comprehensive documentation for resolving "421 Invalid Host Header" errors when using MCP behind proxies or gateways. Includes: - Two resolution options (allowlist vs disable) - Common scenarios (Nginx, Docker) - Security considerations Fixes #1798 Signed-off-by: goingforstudying-ctrl <goingforstudying-ctrl@users.noreply.github.com>
1 parent e65bd53 commit b9f0188

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# DNS Rebinding Protection
2+
3+
The MCP Python SDK includes DNS rebinding protection to prevent DNS rebinding attacks. While this improves security, it may cause existing setups to fail with a **421 Misdirected Request / Invalid Host Header** error if the host header doesn't match the allowed list.
4+
5+
This commonly occurs when using:
6+
7+
- Reverse proxies (Nginx, Caddy, etc.)
8+
- API gateways
9+
- Custom domains
10+
- Docker/Kubernetes networking
11+
12+
## Resolving the Error
13+
14+
Depending on your security requirements, you can resolve this in two ways:
15+
16+
### Option 1: Explicitly Allow Specific Hosts (Recommended for Production)
17+
18+
Use this approach if you are running in production or through a gateway. You can wildcard the ports using `*`.
19+
20+
```python
21+
from mcp.server.fastmcp import FastMCP
22+
from mcp.server.transport_security import TransportSecuritySettings
23+
24+
mcp = FastMCP(
25+
"MyServer",
26+
transport_security=TransportSecuritySettings(
27+
enable_dns_rebinding_protection=True,
28+
# Add your specific gateway or domain here
29+
allowed_hosts=["localhost:*", "127.0.0.1:*", "your-gateway-host:*"],
30+
allowed_origins=["http://localhost:*", "http://your-gateway-host:*"],
31+
)
32+
)
33+
```
34+
35+
### Option 2: Disable DNS Rebinding Protection (Development Only)
36+
37+
Use this approach for local development or if you are managing security at a different layer of your infrastructure.
38+
39+
```python
40+
from mcp.server.fastmcp import FastMCP
41+
from mcp.server.transport_security import TransportSecuritySettings
42+
43+
mcp = FastMCP(
44+
"MyServer",
45+
transport_security=TransportSecuritySettings(
46+
enable_dns_rebinding_protection=False,
47+
)
48+
)
49+
```
50+
51+
## Common Scenarios
52+
53+
### Using with Nginx
54+
55+
If you're using Nginx as a reverse proxy, ensure it's passing the correct headers:
56+
57+
```nginx
58+
location / {
59+
proxy_pass http://localhost:8000;
60+
proxy_set_header Host $host;
61+
proxy_set_header X-Real-IP $remote_addr;
62+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
63+
proxy_set_header X-Forwarded-Proto $scheme;
64+
}
65+
```
66+
67+
And configure your MCP server to allow the Nginx host:
68+
69+
```python
70+
allowed_hosts=["localhost:*", "your-domain.com:*"]
71+
```
72+
73+
### Using with Docker
74+
75+
When running in Docker, you may need to allow the container hostname:
76+
77+
```python
78+
allowed_hosts=["localhost:*", "127.0.0.1:*", "mcp-server:*"]
79+
```
80+
81+
## Security Considerations
82+
83+
- **Production**: Always use Option 1 with explicit host allowlisting
84+
- **Development**: Option 2 is acceptable for local testing
85+
- **Never** disable DNS rebinding protection in production environments exposed to the internet
86+
87+
## Related Issues
88+
89+
- Original implementation: [#861](https://github.com/modelcontextprotocol/python-sdk/pull/861)
90+
- Common errors: [#1797](https://github.com/modelcontextprotocol/python-sdk/issues/1797)

0 commit comments

Comments
 (0)