HIGH dns cache poisoningfastapibasic auth

Dns Cache Poisoning in Fastapi with Basic Auth

Dns Cache Poisoning in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability

DNS cache poisoning (also known as DNS spoofing) occurs when a threat actor injects forged DNS records into a resolver’s cache, causing the victim to be directed to a malicious IP. In FastAPI applications that rely on external hostnames—such as a downstream database, microservice, or third‑party API—and use HTTP Basic Authentication, this attack surface can be critical.

Consider a FastAPI service that resolves an internal host name (e.g., internal.api.example.com) at startup or per request, then uses HTTP Basic Auth to call that downstream service. If the DNS response for internal.api.example.com is poisoned, the application may unknowingly send credentials and sensitive data to an attacker-controlled endpoint. Basic Auth transmits credentials in an Authorization header encoded as Base64 (not encrypted), so any interception or redirection leads to credential exposure. Even if TLS is used downstream, a poisoned DNS entry pointing to a server with a valid certificate for that hostname can complete a TLS handshake, making the redirect hard to detect without additional verification (e.g., certificate pinning or strict hostname checks).

The risk is compounded when FastAPI is deployed in environments where resolver behavior is shared or not strictly controlled, such as containers using the node’s DNS resolver or relying on cloud provider DNS. An attacker who can influence DNS responses—via a compromised network, malicious ISP, or vulnerable resolver—can redirect traffic to a server they control. The FastAPI application, following its logic to include Basic Auth headers, then sends credentials and protected data to the attacker. Because the scan categories of middleBrick include Input Validation and SSRF, such DNS-related weaknesses are surfaced as findings with remediation guidance, emphasizing verification of hostnames and use of secure resolution practices.

Basic Auth-Specific Remediation in Fastapi — concrete code fixes

To mitigate DNS cache poisoning risks when using HTTP Basic Authentication in FastAPI, shift away from Basic Auth in favor of token-based authentication (e.g., OAuth 2.0 bearer tokens) where possible. When Basic Auth is required, enforce strict hostname verification, use a trusted DNS resolver, and avoid relying on system or shared DNS caching without additional safeguards.

Example 1: Using HTTPX with strict hostname verification and custom DNS resolution

Use a dedicated HTTP client like HTTPX, and configure it to validate the server hostname against the expected target, avoiding reliance on the system’s DNS cache for sensitive calls.

import httpx
from starlette.applications import Starlette
from starlette.responses import JSONResponse
import os

EXPECTED_HOST = "internal.api.example.com"

def verify_hostname(response: httpx.Response) -> None:
    # Ensure the resolved hostname matches the expected target
    if response.request.url.hostname != EXPECTED_HOST:
        raise ValueError(f"Hostname mismatch: {response.request.url.hostname} != {EXPECTED_HOST}")

async def call_downstream_service():
    auth_username = os.getenv("DOWNSTREAM_USER")
    auth_password = os.getenv("DOWNSTREAM_PASS")
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            f"https://{EXPECTED_HOST}/v1/resource",
            auth=(auth_username, auth_password),
            timeout=5.0,
        )
        verify_hostname(resp)
        return resp.json()

app = Starlette()

@app.route("/proxy")
async def proxy(request):
    try:
        data = await call_downstream_service()
        return JSONResponse(data)
    except Exception as e:
        return JSONResponse({"error": str(e)}, status_code=502)

Example 2: Overriding DNS resolution with a custom resolver in HTTPX

Force a specific DNS server and validate IPs to reduce reliance on the system resolver, which may be susceptible to cache poisoning.

import httpx
import socket

# Use a trusted DNS server (e.g., 1.1.1.1)
RESOLVER_DNS = "1.1.1.1"
EXPECTED_HOST = "internal.api.example.com"

async def custom_dns_resolver(hostname: str, port: int, is_ssl: bool) -> httpx.AddressTuple:
    if hostname != EXPECTED_HOST:
        raise ValueError(f"Unexpected hostname: {hostname}")
    # Perform DNS lookup using a specific resolver via system call or a DNS library
    # For illustration, we use getaddrinfo; in production, use a DNS-over-HTTPS client or similar.
    family = socket.AF_INET6 if ':' in RESOLVER_DNS else socket.AF_INET
    infos = socket.getaddrinfo(EXPECTED_HOST, port, family, socket.SOCK_STREAM)
    for fam, socktype, proto, canon, sockaddr in infos:
        return httpx.AddressTuple(fam, socktype, proto, sockaddr)
    raise RuntimeError("Resolution failed")

# Example usage with a custom transport (pseudocode integration)
# transport = HTTPXTransport(default_address_fn=custom_dns_resolver)
# client = httpx.Client(transport=transport)

General remediation practices

  • Validate server hostnames and certificate details even when using HTTPS; do not skip verification.
  • Prefer short-lived tokens or session cookies with secure, HttpOnly flags over Basic Auth.
  • Use DNS-over-HTTPS (DoH) or DNSSEC-validating resolvers in your runtime environment where possible.
  • Restrict outbound network paths so that containers or hosts making authenticated calls use controlled resolvers.
  • Monitor and log unexpected hostname or certificate mismatches as potential attack indicators.

Frequently Asked Questions

Does middleBrick detect DNS cache poisoning risks in FastAPI scans?
Yes. middleBrick runs Input Validation and SSRF checks in parallel and surfaces DNS-related weaknesses with severity, findings, and remediation guidance, without claiming to fix or block traffic.
Can using Basic Auth with HTTPS fully protect credentials against DNS cache poisoning?
No. HTTPS protects the content in transit, but DNS cache poisoning can redirect you to a malicious server that presents a valid certificate. Always validate hostnames and prefer token-based authentication over Basic Auth where feasible.