HIGH security misconfigurationfastapiapi keys

Security Misconfiguration in Fastapi with Api Keys

Security Misconfiguration in Fastapi with Api Keys — how this specific combination creates or exposes the vulnerability

Security misconfiguration in FastAPI applications that use API keys often arises from how keys are defined, validated, and scoped. When keys are expected in specific locations (e.g., headers) but the application fails to enforce strict validation, paths with incomplete protections become entry points for unauthorized access.

A common pattern involves declaring an API key scheme but omitting required enforcement on certain routes. For example, using Security dependencies on some endpoints while leaving others without any dependency creates an inconsistency that effectively exposes unprotected paths. Additionally, failing to require the key prefix (e.g., Bearer vs raw key) can allow malformed inputs to pass through if validation logic is permissive.

Misconfiguration also occurs when scopes or roles are declared but not properly enforced. An endpoint might list required scopes in the OpenAPI spec but the dependency implementation skips scope checks, enabling privilege issues across authenticated contexts. Another frequent error is leaking key validation logic into client-side code or logs, which can expose key formats or presence through application output.

Runtime findings frequently reveal these gaps through unauthenticated or insufficiently authenticated probes. Because middleBrick runs 12 security checks in parallel, it flags routes where API key dependencies are missing or inconsistently applied, and cross-references these findings with the OpenAPI/Swagger spec (including $ref resolution) to ensure declared protections match runtime behavior.

For LLM-related security, API keys embedded in prompts or model configurations risk system prompt leakage or unauthorized usage patterns. middleBrick’s LLM/AI Security checks specifically test for exposed key formats in outputs and validate that endpoints requiring keys are not bypassed through prompt injection or jailbreak techniques.

Api Keys-Specific Remediation in Fastapi — concrete code fixes

To remediate API key misconfiguration in FastAPI, consistently apply security dependencies to all routes that require protection, enforce strict key formats, and align runtime behavior with your OpenAPI declarations. Below are concrete examples demonstrating secure patterns.

1. Consistent API key dependency across all routes

Ensure every route that needs protection uses the same API key dependency. Avoid mixing protected and unprotected routes without explicit intent.

from fastapi import FastAPI, Depends, Security, HTTPException, status
from fastapi.security import APIKeyHeader

app = FastAPI()
api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)

def get_api_key(api_key: str = Security(api_key_header)):
    if api_key != "my-secret-key":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Invalid or missing API key"
        )
    return api_key

@app.get("/public")
def public_endpoint():
    return {"message": "public"}

@app.get("/secure")
def secure_endpoint(api_key: str = Security(get_api_key)):
    return {"message": "secure", "api_key_present": bool(api_key)}

2. Enforce key prefix and strict validation

Validate that keys include a required scheme (e.g., Bearer) and reject malformed values early.

from fastapi import FastAPI, Security, HTTPException, status
from fastapi.security import APIKeyHeader

app = FastAPI()
api_key_header = APIKeyHeader(name="Authorization", auto_error=False)

def verify_api_key(authorization: str = Security(api_key_header)):
    if authorization is None:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Authorization header missing")
    if not authorization.startswith("Bearer "):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid authorization format")
    token = authorization[len("Bearer "):]
    if token != "my-secret-key":
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Invalid token")
    return token

@app.get("/items")
def read_items(token: str = Security(verify_api_key)):
    return {"items": ["a", "b"]}

3. Use scopes and enforce them in dependencies

Define and validate scopes to control access per endpoint, ensuring declared scopes are checked at runtime.

from fastapi import FastAPI, Security, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

class Scopes:
    items_read = "items:read"
    items_write = "items:write"

def get_current_user(token: str = Security(oauth2_scheme)):
    # simplified; validate token and extract scopes
    return {"user": "alice", "scopes": [Scopes.items_read]}

def require_scope(required_scope: str):
    def scope_dependency(user: dict = Security(get_current_user)):
        if required_scope not in user.get("scopes", []):
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Insufficient scope")
        return user
    return scope_dependency

@app.get("/items")
def list_items(user: dict = Security(require_scope(Scopes.items_read))):
    return {"items": ["hammer", "nails"]}

@app.post("/items")
def create_item(user: dict = Security(require_scope(Scopes.items_write))):
    return {"status": "created"}

4. Align OpenAPI spec with runtime enforcement

Declare security schemes and requirements in your OpenAPI spec and ensure runtime dependencies reflect them. Use $ref consistently so spec definitions and implementation stay in sync.

openapi: 3.0.3
info:
  title: Secure API
  version: 1.0.0
paths:
  /secure:
    get:
      summary: Requires API key
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: OK
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

5. Avoid key leakage in logs and outputs

Ensure keys are not echoed in responses or logs. When returning diagnostic information, redact or omit the key value.

import logging
logger = logging.getLogger(__name__)

@app.get("/debug")
def debug_key(api_key: str = Security(get_api_key)):
    # Safe: log only presence, not the key value
    logger.info("API key received: %s", bool(api_key))
    return {"ok": True}

Frequently Asked Questions

How does middleBrick detect API key misconfiguration in FastAPI endpoints?
middleBrick runs 12 security checks in parallel and cross-references declared protections in your OpenAPI/Swagger spec (including $ref resolution) with runtime behavior. It flags routes where API key dependencies are missing, inconsistently applied, or not enforced, highlighting gaps between documented and actual security requirements.
Can middleBrick’s LLM/AI Security checks help with API key exposure risks?
Yes. middleBrick’s unique LLM/AI Security checks scan for system prompt leakage, test active prompt injection (including system prompt extraction and jailbreak attempts), and inspect LLM outputs for PII, API keys, and executable code. This helps identify scenarios where API keys embedded in prompts or model configurations might be exposed.