Dangling Dns in Fastapi (Python)
Dangling DNS in FastAPI with Python
Dangling DNS occurs when an API endpoint references a hostname that cannot be resolved to an IP address at runtime. In FastAPI applications built with Python, this typically manifests when:
- Internal service discovery uses hostnames that are only valid in certain environments
- Third-party microservices are invoked via hardcoded hostnames that may not exist in all deployment stages
- Configuration-driven endpoints use DNS names that resolve differently across dev, staging, and production
This creates an unvalidated external resource dependency that attackers can exploit through:
- DNS spoofing attacks where malicious actors register unclaimed hostnames
- Hostname enumeration to discover internal service boundaries
- Cache poisoning to redirect requests to unauthorized endpoints
FastAPI's async nature amplifies the risk because asynchronous HTTP clients often resolve hostnames lazily, potentially exposing race conditions where an attacker registers a hostname between resolution checks.
Real-world example: A FastAPI endpoint that calls an external analytics service using a hostname configured via environment variable:
import os
from httpx import AsyncClient
async def get_analytics():
analytics_host = os.getenv("ANALYTICS_HOST", "analytics.internal")
async with AsyncClient() as client:
response = await client.get(f"http://{analytics_host}/track")
return response.text
If analytics.internal is never registered in DNS, the endpoint becomes dangling. During scanning, middleBrick detects this by sending HTTP requests to the resolved hostname and observing resolution failures or timeout patterns.
This vulnerability maps to OWASP API Top 10 category B01:2023 - Broken Object Level Authorization when the dangling endpoint is used for privilege escalation, or B08:2023 - Software and Data Integrity Failures when the hostname resolution introduces supply chain risks.
Detection through middleBrick's DNS resolution testing identifies:
- Unresolved hostnames during active scanning
- Timeout patterns consistent with non-existent domains
- Inconsistent resolution across scan iterations
- Hardcoded hostnames without fallback validation
Remediation requires explicit hostname validation and environment-aware configuration management, which we detail in the next section.
Python-Specific Remediation in FastAPI
Remediation must address both DNS validation and environment-specific configuration handling. The following Python code demonstrates a secure implementation pattern:
import os
import asyncio
from typing import Optional
from httpx import AsyncClient, ConnectTimeout
# Secure hostname resolution with validation
ALLOWED_HOSTS = {
"analytics": {"env": "production", "required": True},
"staging-analytics": {"env": "staging", "required": False},
"local-analytics": {"env": "development", "required": False}
}
async def get_secure_endpoint():
# Get hostname from secure configuration, not direct env var
env = os.getenv("APP_ENV", "development")
config = ALLOWED_HOSTS.get("analytics", {})
# Validate hostname exists in allowed list
hostname = os.getenv("ANALYTICS_HOST")
if not hostname or hostname not in ALLOWED_HOSTS:
# Fallback to safe default or raise error
raise ValueError(f"Invalid analytics hostname for environment: {env}")
# Validate environment context
if config["env"] != env and config["required"]:
raise RuntimeError(f"Analytics service not available in {env} environment")
# Perform DNS resolution with timeout
try:
loop = asyncio.get_event_loop()
resolved = await loop.getaddrinfo(hostname, None, timeout=5.0)
resolved_host = resolved[0][4][0]
except (asyncio.TimeoutError, socket.gaierror):
raise ConnectionError(f"DNS resolution failed for {hostname}")
# Proceed with validated hostname
async with AsyncClient(timeout=10.0) as client:
response = await client.get(f"http://{resolved_host}/track")
return response.text
if __name__ == "__main__":
import asyncio
asyncio.run(get_secure_endpoint())
Key improvements over vulnerable patterns:
- Explicit hostname whitelisting: Only allows predefined hostnames based on environment
- Context-aware validation: Checks that hostname matches expected environment
- Explicit DNS resolution with timeout: Uses async DNS resolution with explicit timeout handling
- Error handling: Fails fast with descriptive errors instead of proceeding with invalid hostnames
For production systems, combine this with:
- Configuration management that separates environment-specific hostnames
- Health checks that verify DNS resolution during startup
- Service mesh integration that abstracts service discovery
This approach prevents attackers from exploiting unclaimed DNS entries while maintaining FastAPI's async performance characteristics.