django-xff
Django X-Forwarded-For Properly
What it is and what it does
django-xff is middleware that solves a common problem in reverse-proxy deployments: extracting the real client IP address from the X-Forwarded-For header. When requests pass through one or more reverse proxies (load balancers, CDNs, etc.), the original client IP gets buried in a comma-separated list of addresses. A malicious client can prepend fake IPs to this header to spoof their origin, potentially bypassing IP-based security checks or rate limiting.
The middleware works by trusting a fixed depth of proxies—you tell it how many proxies sit between the client and your Django app, and it extracts the IP at the correct position in the chain. It can optionally sanitize the header, validate that the expected number of proxies are present, and reject requests that fail validation. Configuration is entirely through Django settings, with modes ranging from permissive (do nothing if the header is missing) to strict (reject any request that doesn't match the expected proxy depth).
Use it for:
- Running Django behind an AWS Elastic Load Balancer or similar managed proxy where you need accurate client IPs for logging and analytics.
- Implementing IP-based rate limiting or geographic restrictions when requests arrive through a CDN or reverse proxy.
- Rejecting spoofed X-Forwarded-For headers in strict security configurations to prevent attackers from bypassing IP-based access controls.
- Exempting specific URLs (health checks, admin endpoints) from X-Forwarded-For validation while enforcing it elsewhere.
- Debugging request chains by cleaning up the X-Forwarded-For header to remove extraneous entries added by misconfigured proxies.
Worth the install?
AI-flagged interpretation of the facts on this page — verify before relying
Django middleware that extracts the real client IP address from the X-Forwarded-For header by trusting a configurable depth of reverse proxies and sanitizing spoofed entries.
Yes, if you run Django behind one or more reverse proxies and need reliable client IP extraction. The middleware is straightforward to configure and has no external dependencies beyond Django. However, maintenance is dormant (last release 547 days ago); verify that it works with your specific Django and Python versions before relying on it in production, and monitor the repository for any security issues or compatibility breaks.
Install
django-xff on PyPI
pip
pip install django-xffuv
uv add django-xffpoetry
poetry add django-xffInstalling django-xff
Before you install
Low friction: pure Python wheel with only Django as a runtime dependency. Dormant maintenance (last release 547 days ago, last commit 2025-02-13) but repository is not archived and supports Django 4.2, 5.0, and 5.1.
License in practice
MIT License (permissive) — you can use, modify, and distribute this package freely in commercial and private projects with minimal restrictions.
Quickstart
# settings.py
MIDDLEWARE_CLASSES = [
'xff.middleware.XForwardedForMiddleware',
]
XFF_TRUSTED_PROXY_DEPTH = 2
# request.META['REMOTE_ADDR'] will now contain the real client IP
Django must be installed and configured; the middleware must be placed early in MIDDLEWARE_CLASSES to prevent malicious requests from reaching authentication layers.
Verify before relying
- Whether the package works correctly with Django versions beyond 5.1 or with modern Python versions (requires_python is unspecified).
- Real-world effectiveness of spoofing detection modes (XFF_NO_SPOOFING, XFF_STRICT) against current attack patterns.
- Whether the 17 GitHub stars and dormant status indicate sufficient community adoption or testing for production use.
Package facts
| License | MIT License (permissive) |
| Python support | not specified |
| Install friction | low — pure-Python wheel |
| Runtime dependencies | 1 — Django |
| Maintenance | dormant — 547 days since the last release |
| Last repo commit | |
| First released | |
| Downloads | 93,650/month — #13,374 on PyPI (30-day window, as of 2026-08-14) |
| Known vulnerabilities | none known (OSV.dev, checked 2026-08-14) |
Evidence: django_xff-1.5.0-py2.py3-none-any.whl
Tags
More WWW/HTTP packages
urllib3 is an HTTP client library that provides…
permissive · top 100 on PyPI
requestsRequests is a Python HTTP library that…
permissive · top 100 on PyPI
h11h11 is a pure-Python HTTP/1.1 protocol…
permissive · top 100 on PyPI
httpxHTTPX is a fully featured HTTP client library…
permissive · top 100 on PyPI
httpcoreA minimal low-level HTTP client library that…
permissive · top 100 on PyPI
aiohttpaiohttp is an async HTTP client and server…
permissive · top 100 on PyPI
django-ipwareRetrieves the client's IP address from a Django…
permissive · top 5,000 on PyPI
django-revproxyA Django application that forwards HTTP…
copyleft · top 15,000 on PyPI
python-ipwareExtracts a client's IP address from web request…
permissive · top 5,000 on PyPI
django-ebhealthcheckAutomatically adds an Elastic Beanstalk…
permissive · top 15,000 on PyPI
django-allow-cidrA Django middleware that extends ALLOWED_HOSTS…
permissive · top 5,000 on PyPI
proxy-protocolParses and handles the PROXY protocol (v1 and…
permissive · top 5,000 on PyPI
proxyprovidersProvides a unified Python interface for…
permissive · top 15,000 on PyPI
vercel-headersRegisters and exposes request headers for…
permissive · top 5,000 on PyPI
requests-hardenedWraps the requests library to enforce security…
permissive · top 15,000 on PyPI
xclienttransactionGenerates X-Client-Transaction-ID headers for…
permissive · top 15,000 on PyPI