HIGH dns rebindingflaskapi keys

Dns Rebinding in Flask with Api Keys

Dns Rebinding in Flask with Api Keys — how this specific combination creates or exposes the vulnerability

DNS rebinding is a client-side network attack where an adversary tricks a victim’s browser into resolving a domain name to an arbitrary IP address, often bypassing same-origin policy protections. In a Flask application that relies on API keys for access control, combining weak host-header validation with predictable key handling can amplify the impact of a rebinding scenario.

Consider a Flask route that enforces access via an API key passed in a request header:

from flask import Flask, request, jsonify

app = Flask(__name__)
VALID_KEY = "s3cr3t-k3y"

@app.route("/admin")
def admin():
    if request.headers.get("X-API-Key") != VALID_KEY:
        return jsonify({"error": "forbidden"}), 403
    return jsonify({"admin": True})

If an attacker registers a domain (e.g., evil.com) that initially resolves to a benign IP and later rebinds to a target internal service (e.g., 127.0.0.1), a victim’s browser can be made to send requests to the Flask app with the attacker-controlled page context. Because the Flask route above only checks the API key header without validating the request origin or host, the rebinding can bypass source-based restrictions if the API key is leaked or reused across zones.

In a black-box scan, middleBrick’s LLM/AI Security checks include system prompt leakage detection and active prompt injection testing; its API-specific checks include BOLA/IDOR, Property Authorization, and Unsafe Consumption tests that can surface routes where authentication is header-only and lacks host or referer validation. Without additional controls, an API key that is valid across different hostnames or ports can be abused via a rebinding vector to reach admin endpoints or internal services that the client does not directly interact with.

Key risk patterns to watch for:

  • Accepting API keys in headers without verifying the request’s Host header or origin.
  • Using the same API key for both public and administrative endpoints, increasing the blast radius if the key is exfiltrated via rebinding.
  • Relying solely on network-based perimeter controls in environments where DNS rebinding can circumvent IP-based assumptions.

Api Keys-Specific Remediation in Flask — concrete code fixes

To reduce DNS rebinding risk when using API keys in Flask, enforce strict host validation, scope keys to specific origins, and avoid key reuse across trust boundaries. Below are concrete, secure patterns you can apply.

1. Validate Host and Origin

Explicitly check the Host header and, when relevant, the Origin header before honoring the API key:

from flask import Flask, request, jsonify, abort

app = Flask(__name__)
VALID_KEY = "s3cr3t-k3y"
ALLOWED_HOSTS = {"api.yourdomain.com", "app.yourdomain.com"}

@app.before_request
def enforce_host_and_key():
    if request.path.startswith("/admin"):
        if request.headers.get("Host") not in ALLOWED_HOSTS:
            abort(403, description="Host not allowed")
        if request.headers.get("X-API-Key") != VALID_KEY:
            abort(403, description="Invalid API key")
        # Optional: enforce Origin for cross-origin requests
        origin = request.headers.get("Origin")
        if origin and not origin.startswith("https://api.yourdomain.com"):
            abort(403, description="Origin not allowed")

This ensures that even if DNS rebinding alters the resolved IP, the Host check will fail for unexpected domains, and the API key is not honored on unauthorized hosts.

2. Key Scoping and Short-Lived Tokens

Instead of a single static key, scope keys per client or per route and rotate them frequently. For example, issue short-lived tokens stored server-side and validated against a small scope:

import time
from flask import Flask, request, jsonify, abort

app = Flask(__name__)
# Simulated store; in production use a secure cache or DB
ACTIVE_TOKENS = {
    "token-a": {"expires_at": time.time() + 300, "allowed_host": "api.yourdomain.com"},
}

def validate_token(token, host):
    entry = ACTIVE_TOKENS.get(token)
    if not entry:
        return False
    if time.time() > entry["expires_at"]:
        return False
    if host != entry["allowed_host"]:
        return False
    return True

@app.route("/data")
def get_data():
    token = request.headers.get("X-API-Key")
    if not validate_token(token, request.headers.get("Host")):
        abort(403, description="Invalid or scoped token")
    return jsonify({"data": "safe"})

This approach limits the usefulness of a leaked key and reduces the window for rebinding attacks that rely on a long-lived, broadly trusted key.

3. Use HTTPS and HSTS

Serve your Flask app over HTTPS and include HTTP Strict Transport Security headers to prevent downgrade attacks that could make rebinding easier to execute in mixed-content scenarios:

from flask import Flask
from flask_talisman import Talisman

app = Flask(__name__)
Talisman(app, force_https=True, hsts=True)

Although not a direct API key fix, HTTPS and HSTS reduce the feasibility of DNS rebinding by ensuring responses are delivered over a cryptographically verified channel.

4. Rate Limiting and Monitoring

Apply per-host or per-key rate limits to detect abnormal request patterns that may indicate rebinding attempts:

from flask import Flask
from flask_limiter import Limiter

app = Flask(__name__)
limiter = Limiter(app, key_func=lambda: request.headers.get("Host", "unknown"))

@app.route("/admin")
@limiter.limit("10/minute")
def admin():
    if request.headers.get("X-API-Key") != "s3cr3t-k3y":
        return jsonify({"error": "forbidden"}), 403
    return jsonify({"admin": True})

middleBrick’s Pro plan includes continuous monitoring and can integrate with CI/CD to alert on configurations that may expose keys or weak host validation, helping you detect risky deployments before rebinding scenarios are weaponized.

Frequently Asked Questions

Can DNS rebinding bypass API key protections if the Host header is validated?
If you validate the Host header on every request and reject requests for unexpected hosts, DNS rebinding is unlikely to bypass your API key protections because the attacker cannot make the victim’s browser resolve to an allowed hostname.
Is using a static API key sufficient if I enforce HTTPS and HSTS?
HTTPS and HSTS protect transport integrity but do not prevent header-only authentication risks. Static keys should be scoped, rotated, and combined with host and origin validation to reduce exposure from DNS rebinding or token leakage.