HIGH dns rebindingdjangopython

Dns Rebinding in Django (Python)

Dns Rebinding in Django with Python — how this specific combination creates or exposes the vulnerability

DNS Rebinding is a client-side attack where an attacker causes a victim’s browser to send requests to an internal or restricted host by changing the DNS answer after the initial page load. In Django applications written in Python, this becomes relevant when the server trusts the Host header or uses the request’s host for redirects, dynamic site names, or origin checks. Because Django typically runs behind a reverse proxy, the combination of Python application logic, proxy configuration, and browser behavior can allow an internal service to be reached through a seemingly external domain.

Consider a Django view that performs a redirect based on a user-supplied URL or hostname:

from django.http import HttpResponseRedirect
from django.views.decorators.http import require_http_methods

@require_http_methods(["GET"])
def redirect_to_host(request):
    host = request.META.get("HTTP_HOST", "")
    return HttpResponseRedirect(f"http://{host}/dashboard/")

If the proxy does not strictly enforce or rewrite the Host header, an attacker can supply an internal IP (e.g., 127.0.0.1 or 192.168.1.1) as the hostname. After the initial page load from a benign domain, the attacker can change the DNS record to point to an internal service, causing the victim’s browser to follow the redirect and interact with the internal host as if it were the trusted origin. This can lead to unauthorized access to internal APIs or management interfaces, and may be combined with other vulnerabilities such as BOLA/IDOR if the session cookies are sent to the internal host.

Django’s ALLOWED_HOSTS setting mitigates some host header abuse, but it does not prevent rebinding after the initial request once the browser is on a page served from an allowed host. Additionally, if the Django app validates origins by inspecting headers like Origin or Referer without also validating the resolved IP, an attacker can bypass checks through DNS manipulation. This is especially risky when Python code uses request metadata to construct URLs or make server-side fetches, effectively turning the Django app into a proxy that may reveal internal resources to an authenticated client.

To detect such patterns in your stack, middleBrick scans your public endpoint and flags insecure redirect behavior and missing host validation as part of its Authentication and Property Authorization checks. By correlating OpenAPI/Swagger specs with runtime findings, the scanner can highlight mismatches between declared allowed hosts and observed redirect behavior without requiring credentials.

Python-Specific Remediation in Django — concrete code fixes

Defending against DNS Rebinding in Django with Python centers on strict host validation, avoiding dynamic redirects based on client-supplied headers, and ensuring that server-side fetches do not inadvertently expose internal endpoints. The following patterns demonstrate concrete, safe implementations.

1. Validate and normalize the Host header

Instead of directly using request.META["HTTP_HOST"], compare it against a known set of domains or IPs and normalize the value before use:

from django.http import HttpResponseBadRequest, HttpResponseRedirect
from django.conf import settings
import re

ALLOWED_DOMAINS = {"api.example.com", "www.example.com"}

def is_safe_host(host):
    # Basic domain/IP validation; extend with your organization’s rules
    if not host:
        return False
    if host in ALLOWED_DOMAINS:
        return True
    # Reject IPs unless explicitly allowed
    if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", host):
        return False
    return False

@require_http_methods(["GET"])
def safe_redirect(request):
    host = request.META.get("HTTP_HOST", "")
    if not is_safe_host(host):
        return HttpResponseBadRequest("Invalid host")
    # Use a canonical, server-controlled target instead of dynamic host
    return HttpResponseRedirect("/dashboard/")

2. Avoid client-controlled redirects or URL constructions

Do not build redirect URLs from user input. If you must redirect, use a fixed path or a server-side mapping:

from django.shortcuts import redirect

def redirect_dashboard(request):
    # Always redirect to a path relative to the current host
    return redirect("/dashboard/")

3. Secure server-side HTTP requests

If your Python code makes outbound HTTP requests (e.g., calling another internal service), resolve hostnames once at configuration time and avoid using runtime-supplied hostnames:

import requests
from django.conf import settings

# Resolve once at startup or via settings
INTERNAL_API_BASE = "https://internal-api.example.com"

def call_internal_api(resource):
    url = f"{INTERNAL_API_BASE}/{resource}"
    # Use configured timeouts and TLS verification
    response = requests.get(url, timeout=5, verify=True)
    response.raise_for_status()
    return response.json()

4. Tighten ALLOWED_HOSTS and proxy headers

Set ALLOWED_HOSTS to the exact public hostnames and ensure your reverse proxy sets headers like X-Forwarded-Host consistently. In Django settings:

# settings.py
ALLOWED_HOSTS = ["api.example.com", "www.example.com"]
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

By combining these Python-specific practices with continuous scanning via middleBrick’s CLI or GitHub Action, you can detect risky redirect logic and missing host validation early in development. The dashboard helps track improvements over time, while the Pro plan’s continuous monitoring can alert you if a future deployment introduces a permissive redirect pattern.

Frequently Asked Questions

Can DNS Rebinding affect Django apps that use ALLOWED_HOSTS?
Yes. ALLOWED_HOSTS protects against Host header abuse, but does not prevent a victim’s browser from following a redirect or making requests to an internal host after the page has loaded. Validate and normalize hosts in Python code and avoid dynamic redirects based on client input.
Does middleBrick fix DNS Rebinding issues automatically?
middleBrick detects and reports findings with remediation guidance; it does not automatically fix or block requests. Use the provided remediation steps in your Python Django code and validate host headers explicitly.