Skip to content

Commit 9efde4a

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
1 parent e65bd53 commit 9efde4a

File tree

1 file changed

+89
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)