HIGH ssrf server sidefastapijwt tokens

Ssrf Server Side in Fastapi with Jwt Tokens

Ssrf Server Side in Fastapi with Jwt Tokens — how this specific combination creates or exposes the vulnerability

Server-side request forgery (SSRF) in FastAPI occurs when an application fetches a remote resource from a user-supplied URL without adequate validation. When endpoints that accept target URLs also enforce JWT token validation, developers may assume the JWT protects the operation. In practice, the JWT secures authorization from the client to the API, but it does not restrict what the server can request once it acts as a client. An attacker can supply a malicious internal address (e.g., http://169.254.169.254/latest/meta-data/iam/security-credentials/) as the target, and the server-side request will include the runtime service’s credentials regardless of the validity or scope of the attacker’s JWT.

In FastAPI, this risk is often realized when an endpoint uses httpx or requests to call a user-provided URL while attaching outbound Authorization: Bearer headers derived from the JWT. If the endpoint forwards or mirrors the JWT to the target, you may inadvertently propagate identity tokens to internal services. Even without forwarding, SSRF can bypass network-level trust boundaries: internal metadata services, container orchestration endpoints, or local TCP ports (e.g., Redis on 6379) become reachable from the server. Common misconfigurations include missing allowlists for hostnames and schemes, failing to disable redirects to private IP ranges, and not enforcing strict timeout and connection pooling controls.

Because middleBrick scans unauthenticated attack surfaces, it can detect SSRF-like behaviors by probing endpoints that accept URLs and inspecting whether the API exposes internal resources. The scan does not rely on internal architecture; it observes responses for data leakage or unexpected redirects. Findings typically map to OWASP API Top 10 A01:2023 — Broken Object Level Authorization when authorization checks do not apply to outbound calls, and A05:2021 — Security Misconfiguration when network controls are insufficient. Remediation must focus on input validation, network segregation, and outbound request hardening rather than JWT introspection alone.

Jwt Tokens-Specific Remediation in Fastapi — concrete code fixes

To mitigate SSRF when JWT tokens are in play, treat the token as an authentication credential for inbound requests and ensure outbound calls are strictly controlled. Do not forward the client’s JWT to arbitrary destinations, and do not rely on the presence of a valid JWT to decide whether a target URL is safe.

Use an allowlist of permitted hosts and ports for outbound requests. Validate the scheme (https only) and reject private IP ranges, localhost, and loopback addresses. Enforce timeouts and disable redirects to prevent SSRF via chained hops.

from typing import Optional
import httpx
from fastapi import FastAPI, Depends, HTTPException, Security
from pydantic import HttpUrl, ValidationError
import ipaddress

app = FastAPI()

# Example inbound dependency that verifies a JWT and extracts claims (simplified)
async def get_current_user(token: str = Security(oauth2_scheme)):
    # Replace with your JWT validation logic
    return {"sub": "user-id", "scope": "fetch:resources"}

def is_private_url(url: HttpUrl) -> bool:
    try:
        host = url.hostname or ""
        port = url.port or (443 if url.scheme == "https" else 80)
        ip = ipaddress.ip_address(host)
        return ip.is_private or ip.is_loopback or ip.is_link_local
    except (ValueError, AttributeError):
        # If hostname is not an IP, perform DNS-aware checks cautiously
        return False

ALLOWED_HOSTS = {"api.example.com", "data.example.com"}

@app.get("/fetch-external")
async def fetch_external(
    target: HttpUrl,
    user: dict = Security(get_current_user)
):
    if target.hostname not in ALLOWED_HOSTS:
        raise HTTPException(status_code=400, detail="Target host not allowed")
    if target.scheme != "https":
        raise HTTPException(status_code=400, detail="Only HTTPS targets allowed")
    if is_private_url(target):
        raise HTTPException(status_code=400, detail="Private target not allowed")

    timeout = httpx.Timeout(5.0, connect=2.0)
    async with httpx.AsyncClient(timeout=timeout, follow_redirects=False) as client:
        headers = {"Authorization": f"Bearer {user.get('token', '')}"} if user.get('token') else {}
        resp = await client.get(target, headers=headers)
        resp.raise_for_status()
        return {"status": resp.status_code, "body_length": len(resp.content)}

If you need to call downstream services on behalf of the user, avoid propagating the original JWT. Instead, use a scoped server-side token or an opaque reference that downstream services can validate against a limited scope. For services that require a token, map the user’s permissions to a minimal set of claims rather than reusing the inbound token.

middleBrick’s LLM/AI Security checks can identify whether endpoints leak system prompts or expose tokens in outputs, complementing SSRF defenses by ensuring that compromised endpoints do not amplify credential exposure. The CLI tool allows you to integrate scans into scripts, while the GitHub Action can enforce a maximum risk score before merges, ensuring SSRF and related findings are caught early.

Frequently Asked Questions

Does using a JWT token in my FastAPI requests prevent SSRF?
No. A JWT secures inbound authentication but does not restrict what your server can request. SSRF depends on how the server makes outbound calls, so you must validate target URLs and avoid forwarding the client’s JWT to arbitrary endpoints.
How does middleBrick handle SSRF detection without authentication?
middleBrick scans the unauthenticated attack surface and observes responses for signs of SSRF, such as redirection to internal resources or data leakage. It does not rely on internal architecture and maps findings to frameworks like OWASP API Top 10.