{"id":"CVE-2025-59152","aliases":["GHSA-hm36-ffrh-c77c","PYSEC-2026-1553"],"title":"Litestar X-Forwarded-For Header Spoofing Vulnerability Enables Rate Limit Evasion","summary":"Litestar X-Forwarded-For Header Spoofing Vulnerability Enables Rate Limit Evasion","severity":"high","cvss":7.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","vendor":"litestar","product":"litestar","ecosystem":"pip","affected":["litestar >= 2.17.0, < 2.18.0"],"patched":["litestar 2.18.0"],"published":"2025-10-06","updated":"2026-07-07","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-hm36-ffrh-c77c","references":[{"url":"https://github.com/litestar-org/litestar/security/advisories/GHSA-hm36-ffrh-c77c"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2025-59152"},{"url":"https://github.com/litestar-org/litestar/commit/42a89e043e50b515f8548a93954fe143f63cf9fb"},{"url":"https://github.com/litestar-org/litestar"},{"url":"https://github.com/litestar-org/litestar/blob/26f20ac6c52de2b4bf81161f7560c8bb4af6f382/litestar/middleware/rate_limit.py#L127"}],"tags":["osv","pip"],"epss":0.00485,"epssPercentile":0.40744,"ingestedAt":"2026-07-08T18:25:50.273Z","slug":"CVE-2025-59152","body":"## Overview\n\nWhile testing Litestar's RateLimitMiddleware, I discovered that rate limits can be completely bypassed by manipulating the X-Forwarded-For header. This renders IP-based rate limiting ineffective against determined attackers.\n\n## The Problem\n\nLitestar's RateLimitMiddleware uses `cache_key_from_request()` to generate cache keys for rate limiting. When an X-Forwarded-For header is present, the middleware trusts it unconditionally and uses its value as part of the client identifier.\n\nSince clients can set arbitrary X-Forwarded-For values, each different spoofed IP creates a separate rate limit bucket. An attacker can rotate through different header values to avoid hitting any single bucket's limit.\n\nLooking at the relevant code in `litestar/middleware/rate_limit.py` around [line 127](https://github.com/litestar-org/litestar/blob/26f20ac6c52de2b4bf81161f7560c8bb4af6f382/litestar/middleware/rate_limit.py#L127), there's no validation of proxy headers or configuration for trusted proxies.\n\n## Reproduction Steps\n\nHere's a minimal test case\n\n```python\nfrom litestar import Litestar, get\nfrom litestar.middleware.rate_limit import RateLimitConfig\nimport uvicorn\n\n@get(\"/api/data\")\ndef get_data() -> dict:\n    return {\"message\": \"sensitive data\"}\n\nrate_config = RateLimitConfig(rate_limit=(\"minute\", 2))\n\napp = Litestar(\n    route_handlers=[get_data],\n    middleware=[rate_config.middleware]\n)\n\nif __name__ == \"__main__\":\n    uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\nTesting the bypass\n\n```bash\n# Normal requests get rate limited after 2 requests\ncurl http://localhost:8000/api/data  # 200 OK\ncurl http://localhost:8000/api/data  # 200 OK  \ncurl http://localhost:8000/api/data  # 429 Too Many Requests\n\n# But spoofing X-Forwarded-For bypasses the limit entirely\ncurl -H \"X-Forwarded-For: 192.168.1.100\" http://localhost:8000/api/data  # 200 OK\ncurl -H \"X-Forwarded-For: 192.168.1.101\" http://localhost:8000/api/data  # 200 OK\ncurl -H \"X-Forwarded-For: 192.168.1.102\" http://localhost:8000/api/data  # 200 OK\n```\n\n## Security Impact\n\nThis vulnerability has several concerning implications:\n\nBrute Force Protection Bypass: Authentication endpoints protected by rate limiting become vulnerable to credential stuffing attacks. An attacker can attempt thousands of login combinations from a single source.\n\nAPI Abuse: Public APIs relying on rate limiting for abuse prevention can be scraped or hammered without restriction.\n\nResource Exhaustion: While not a traditional DoS, the ability to bypass rate limits means attackers can consume more server resources than intended.\n\nThe issue is particularly problematic because many developers deploy Litestar applications directly (not behind a proxy) during development or in containerized environments, making this attack vector accessible.\n\n## Potential Solutions\n\nAfter reviewing how other frameworks handle this:\n\n- Default to socket IP only: Don't trust proxy headers unless explicitly configured\n- Trusted proxy configuration: Add settings to specify which proxy IPs are allowed to set forwarded headers\n- Header validation: Implement basic validation of forwarded IP formats\n\nDjango handles this through `SECURE_PROXY_SSL_HEADER` and trusted proxy lists. Express.js has similar trusted proxy configurations.\n\nFor immediate mitigation, applications can deploy behind a properly configured reverse proxy that strips/overwrites client-controllable headers before they reach Litestar.\n\n## Environment Details\n\n- Litestar version: 2.17.0\n- Python: 3.11\n\nThis affects any Litestar application using RateLimitMiddleware with default settings, which likely includes most applications that implement rate limiting.\n\n## Affected packages\n\n- `litestar >= 2.17.0, < 2.18.0`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `litestar 2.18.0`","depth":"twilight","depthScore":41,"depthScoreParts":{"impact":41.3,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[]}