HIGH dns cache poisoningflaskbearer tokens

Dns Cache Poisoning in Flask with Bearer Tokens

Dns Cache Poisoning in Flask with Bearer Tokens — how this specific combination creates or exposes the vulnerability

DNS cache poisoning (also known as DNS spoofing) occurs when an attacker injects a malicious DNS record into a resolver’s cache, causing domain lookups to return attacker-controlled IP addresses. In a Flask application that relies on external service discovery or configuration endpoints, poisoned DNS responses can redirect traffic to a malicious host. If the application then uses Bearer Tokens for authentication, those tokens can be inadvertently sent to the malicious endpoint, leading to token theft or unauthorized API access.

The combination is particularly risky because Flask often integrates with third-party APIs and microservices. When Flask code resolves a hostname at runtime—such as through requests.get() or an HTTP client used to call an authorization server—a poisoned DNS entry can point to an attacker’s server. If the request includes a Bearer Token in the Authorization header, the token is transmitted to the attacker. Even if the token is not directly leaked, an attacker might intercept or manipulate the request path, leading to token replay or privilege escalation. This risk is amplified when Flask applications run in containerized or cloud environments where service discovery and dynamic DNS are common.

Consider a Flask app that retrieves an OAuth2 introspection endpoint via a hostname that could be subject to DNS manipulation:

import requests

OAUTH_INTROSPECTION_URL = 'https://auth.example.com/introspect'
BEARER_TOKEN = 'secret-token-123'

def introspect_token(token):
    headers = {'Authorization': f'Bearer {token}'}
    response = requests.get(OAUTH_INTROSPECTION_URL, headers=headers)
    return response.json()

If an attacker poisons the DNS for auth.example.com to point to a malicious server, the Flask app will send the Bearer Token to the attacker. Because the token is embedded in the Authorization header, it becomes directly exposed. This scenario highlights the importance of validating not only the application’s logic but also the integrity of network resolution paths, especially when handling credentials.

Moreover, Flask applications that use service clients initialized with hostnames (rather than IP addresses) are susceptible to runtime DNS lookups. If those clients are configured to include Bearer Tokens in every request—such as API gateways or microservice clients—a single poisoned DNS entry can compromise multiple services. The risk is not limited to outbound calls; internal service meshes that rely on DNS-based routing can also be affected, making token leakage a cross-cutting concern.

While middleBrick does not fix runtime configuration issues, it can detect insecure patterns in API specifications and runtime behavior, such as unauthenticated endpoints or missing input validation, that may coexist with DNS-related risks. Using the CLI (middlebrick scan <url>) or integrating the GitHub Action into CI/CD pipelines can help identify related misconfigurations before deployment.

Bearer Tokens-Specific Remediation in Flask — concrete code fixes

Remediation focuses on minimizing exposure of Bearer Tokens and ensuring that DNS resolution and HTTP requests are as resilient as possible. Below are concrete, secure coding patterns for Flask applications.

1. Avoid embedding tokens in code or configuration

Never hardcode Bearer Tokens in source code or configuration files. Instead, use environment variables or a secure secrets manager. This reduces the risk of token leakage through version control or logs.

import os
from flask import Flask, request
import requests

app = Flask(__name__)

# Load token from environment at runtime
BEARER_TOKEN = os.getenv('OAUTH_INTROSPECTION_TOKEN')
if not BEARER_TOKEN:
    raise RuntimeError('Missing OAUTH_INTROSPECTION_TOKEN environment variable')

OAUTH_INTROSPECTION_HOST = os.getenv('OAUTH_INTROSPECTION_HOST', 'auth.example.com')

def introspect_token(token):
    url = f'https://{OAUTH_INTROSPECTION_HOST}/introspect'
    headers = {'Authorization': f'Bearer {token}'}
    response = requests.get(url, headers=headers, timeout=5)
    response.raise_for_status()
    return response.json()

2. Use IP addresses or certificate pinning where feasible

For critical endpoints, prefer IP addresses or implement certificate pinning to reduce reliance on DNS. While not always practical, this limits the attack surface to DNS manipulation.

import requests

# Example using a pinned IP and host header
OAUTH_INTROSPECTION_URL = 'https://192.0.2.1/introspect'

def introspect_token_with_pinning(token):
    headers = {
        'Authorization': f'Bearer {token}',
        'Host': 'auth.example.com'  # Ensure correct host header
    }
    response = requests.get(OAUTH_INTROSPECTION_URL, headers=headers, verify=True, timeout=5)
    return response.json()

3. Validate and sanitize external configuration

If your application dynamically constructs endpoints, validate hostnames against an allowlist and reject unexpected domains.

ALLOWED_HOSTS = {'auth.example.com', 'api.partner.com'}

def safe_request(url, token):
    from urllib.parse import urlparse
    host = urlparse(url).hostname
    if host not in ALLOWED_HOSTS:
        raise ValueError(f'Host {host} is not allowed')
    headers = {'Authorization': f'Bearer {token}'}
    response = requests.get(url, headers=headers, timeout=5)
    return response.json()

4. Leverage Flask middleware for token protection

Use before/after request hooks to ensure tokens are only attached to trusted outgoing calls and to log suspicious activity.

@app.before_request
def attach_bearer_token():
    # Example: attach token only for specific blueprints
    if request.blueprint in ['api_client']:
        g.token = os.getenv('SERVICE_TOKEN')

@app.after_request
def log_outgoing_token_usage(response):
    # Audit logging can help detect misuse
    if hasattr(g, 'token'):
        app.logger.info('Bearer token used for outgoing call')
    return response

5. Use the CLI and CI/CD integration for early detection

Run middlebrick scan <url> to identify API endpoints that handle authentication and assess their resilience to network-level attacks. For continuous protection, add the GitHub Action to fail builds if insecure patterns are detected in OpenAPI specs or runtime behavior.

Frequently Asked Questions

Can DNS cache poisoning affect internal Flask services that do not use Bearer Tokens?
Yes. DNS cache poisoning can redirect any outbound request, including internal service calls, to malicious hosts. While Bearer Tokens are high-value targets, any request manipulation can lead to data exposure or service disruption, so defense in depth is essential.
Does middleBrick detect DNS cache poisoning vulnerabilities in Flask APIs?
middleBrick does not directly test DNS cache poisoning, as it operates at the API specification and runtime interaction level. It can identify insecure transport configurations or missing input validation that may coexist with DNS risks. Use the CLI or GitHub Action to surface related issues.