HIGH ssrf server sideflaskapi keys

Ssrf Server Side in Flask with Api Keys

Ssrf Server Side in Flask with Api Keys — how this specific combination creates or exposes the vulnerability

Server-side request forgery (SSRF) in a Flask application that uses API keys creates a scenario where an attacker can force the server to make unintended requests to internal or third-party services, often bypassing network-level isolation. API keys are typically stored in server-side code or injected as environment variables; they are not meant to be exposed to clients. When Flask endpoints accept user-supplied URLs and make outbound HTTP requests using a shared API key, the server may act as a proxy that can be abused.

For example, consider a Flask route that fetches third-party data and includes an API key in headers. If the target URL is user-controlled and lacks strict validation, an attacker can supply an internal address (e.g., http://169.254.169.254/latest/meta-data/iam/security-credentials/ on AWS) to leak credentials. The API key in the request headers does not protect the backend because it is used by the server itself, not validated against the caller. This combination amplifies risk: the API key may have elevated permissions, and SSRF can pivot to metadata services, internal APIs, or other services bound to localhost or private networks.

Insecure patterns include using requests.get(user_url, headers={"Authorization": f"Bearer {api_key}"}) without URL allowlisting or schema restrictions. An attacker might supply `http://localhost:8000/admin` or a file:// URL to trigger local file inclusion or service probing. Even if the API key is scoped to a third-party service, SSRF can lead to unintended interactions, such as triggering internal webhooks or exfiltrating data via the server’s identity.

middleBrick detects SSRF and related API security risks in Flask apps during unauthenticated scans. By submitting your endpoint URL to the tool, you can identify whether user-supplied input can influence outbound requests and whether API keys are handled in a way that could be leveraged in chained attacks. This insight complements broader practices like input validation and network segmentation.

Api Keys-Specific Remediation in Flask — concrete code fixes

To mitigate SSRF when using API keys in Flask, you must separate the handling of user input from the use of secrets. Never forward user-controlled URLs to outbound requests, and never include API keys in responses or logs. Apply strict allowlisting for schemas and hosts, and prefer server-side configuration for secrets rather than dynamic assembly.

Insecure example to avoid

import requests
from flask import Flask, request, jsonify

app = Flask(__name__)
API_KEY = "super-secret-key"  # Ideally injected via env var

@app.route("/fetch")
def fetch():
    url = request.args.get("url")
    headers = {"Authorization": f"Bearer {API_KEY}"}
    resp = requests.get(url, headers=headers, timeout=5)
    return jsonify(resp.json())

Secure remediation with allowlisting and env-based secrets

import os
import re
import requests
from flask import Flask, request, jsonify, abort

app = Flask(__name__)
API_KEY = os.environ.get("API_KEY")
if not API_KEY:
    raise RuntimeError("API_KEY environment variable is required")

ALLOWED_HOSTS = {"api.example.com", "data.example.org"}
ALLOWED_SCHEMAS = {"https"}

def is_allowed_url(url: str) -> bool:
    # Basic structural checks
    if not re.match(r"^https?://", url):
        return False
    from urllib.parse import urlparse
    parsed = urlparse(url)
    if parsed.scheme not in ALLOWED_SCHEMAS:
        return False
    if parsed.hostname not in ALLOWED_HOSTS:
        return False
    # Reject dangerous patterns
    if ".." in parsed.path or "//" in parsed.path:
        return False
    return True

@app.route("/fetch")
def fetch():
    url = request.args.get("url", "")
    if not is_allowed_url(url):
        abort(400, description="Invalid or disallowed URL")
    headers = {"Authorization": f"Bearer {API_KEY}"}
    resp = requests.get(url, headers=headers, timeout=5)
    resp.raise_for_status()
    return jsonify(resp.json())

Operational practices

  • Store API keys as environment variables or use your platform’s secret manager; never commit them to source control.
  • Apply host and schema allowlists rigorously; prefer whitelisting over blacklists.
  • Use short timeouts and disable redirects for outbound calls to reduce SSRR impact surface.
  • Log request metadata without including the API key; ensure logs are protected.

If you use the middleBrick CLI (middlebrick scan <url>), you can validate that your remediation works by confirming that the report shows no SSRF findings and that API key usage is not exposed in responses. For teams that need continuous assurance, the Pro plan provides scheduled scans and CI/CD integration to catch regressions before deployment.

Frequently Asked Questions

Can API keys alone prevent SSRF in Flask?
No. API keys are credentials used by the server; SSRF is about where the server makes requests. Protecting endpoints requires input validation, allowlisting, and restricting outbound connections, not keeping keys secret alone.
Does middleBrick fix SSRF or remove API keys from my code?
middleBrick detects and reports findings with remediation guidance; it does not fix, patch, block, or modify code. You must apply the guidance to remediate SSRF and API key handling.