Summary
When MCP_TRUST_PROXY_HEADERS=true, the middleware directly trusts X-Forwarded-For / X-Real-IP from the incoming request and uses them for allowlist decisions.
There is no concept of trusted reverse proxies or trusted proxy CIDRs, so any client that can connect directly to the server can spoof these headers and potentially bypass the IP allowlist.
Evidence
- Client IP extraction trusts forwarded headers unconditionally when enabled:
src/mcp_server_starrocks/http_security.py:399-409
- The resulting IP is then used by the allowlist check:
src/mcp_server_starrocks/http_security.py:411-445
- Tests currently validate the happy path for spoofed
X-Forwarded-For headers, but there is no protection against direct-client spoofing:
tests/test_http_security.py:142-156
Risk
A deployment behind a reverse proxy can be made vulnerable if the backend is also reachable directly, or if the proxy chain is not tightly controlled. In that case, a direct client can self-assert an internal/private IP and bypass the IP filter.
Suggested Fix
- Add a
MCP_TRUSTED_PROXIES / CIDR-based trusted proxy list.
- Only honor forwarded headers when
request.client.host is a trusted proxy.
- Otherwise, ignore forwarded headers and use the socket peer address.
- Add negative tests showing spoofed headers from untrusted peers are rejected.
Summary
When
MCP_TRUST_PROXY_HEADERS=true, the middleware directly trustsX-Forwarded-For/X-Real-IPfrom the incoming request and uses them for allowlist decisions.There is no concept of trusted reverse proxies or trusted proxy CIDRs, so any client that can connect directly to the server can spoof these headers and potentially bypass the IP allowlist.
Evidence
src/mcp_server_starrocks/http_security.py:399-409src/mcp_server_starrocks/http_security.py:411-445X-Forwarded-Forheaders, but there is no protection against direct-client spoofing:tests/test_http_security.py:142-156Risk
A deployment behind a reverse proxy can be made vulnerable if the backend is also reachable directly, or if the proxy chain is not tightly controlled. In that case, a direct client can self-assert an internal/private IP and bypass the IP filter.
Suggested Fix
MCP_TRUSTED_PROXIES/ CIDR-based trusted proxy list.request.client.hostis a trusted proxy.