HIGH cryptographic failuresfastapi

Cryptographic Failures in Fastapi

How Cryptographic Failures Manifests in Fastapi

Cryptographic failures in FastAPI applications typically emerge through several common patterns that stem from both framework defaults and developer oversights. Understanding these specific manifestations is crucial for securing FastAPI APIs.

Weak Default Settings

FastAPI's defaults can be problematic. When using SECRET_KEY for session management without proper configuration, applications often default to insecure settings. The SECRET_KEY environment variable must be sufficiently random—at least 32 bytes of entropy—but many implementations use predictable values.

Insecure JWT Implementation

FastAPI's JWT handling often fails when developers use weak signing algorithms or expose endpoints that accept any algorithm. Consider this vulnerable pattern:

from fastapi import FastAPI, Depends
from fastapi.security import OAuth2PasswordBearer
from jose import jwt

oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token')

def verify_token(token: str = Depends(oauth2_scheme)):
    try:
        # Vulnerable: no algorithm validation
        payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256', 'none'])
        return payload
    except:
        raise HTTPException(status_code=401, detail='Invalid token')

This code accepts both HS256 and 'none' algorithms, allowing attackers to forge tokens by removing signatures entirely.

Improper Secret Management

FastAPI applications frequently hardcode secrets or use weak key derivation functions. A common anti-pattern:

# Vulnerable: hardcoded secret
SECRET_KEY = 'this_is_not_secure_at_all_1234567890'

Even when using environment variables, developers might generate weak keys or reuse keys across environments.

Insufficient Key Length

FastAPI's cryptography often uses inadequate key lengths. For AES encryption, using 128-bit keys instead of 256-bit keys leaves applications vulnerable to brute-force attacks. Similarly, RSA keys shorter than 2048 bits are considered weak by modern standards.

Timing Attacks

FastAPI's password comparison implementations often use naive equality checks that leak timing information:

# Vulnerable: timing attack possible
if user.password == submitted_password:
    return True

Attackers can exploit these timing differences to recover passwords character by character.

Insufficient Entropy

FastAPI applications frequently use predictable random number generators for cryptographic operations. Using Python's random module instead of secrets module for token generation creates vulnerabilities:

# Vulnerable: predictable tokens
import random

def generate_token():
    return ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=16))

The secrets module should always be used for cryptographic operations in FastAPI.

Fastapi-Specific Detection

Detecting cryptographic failures in FastAPI requires both static analysis and runtime scanning. middleBrick provides specialized detection for FastAPI applications, identifying vulnerabilities that traditional scanners miss.

Runtime Scanning with middleBrick

middleBrick's black-box scanning approach is particularly effective for FastAPI applications because it tests the actual running API without requiring source code access. The scanner identifies cryptographic weaknesses through active probing:

# Scan your FastAPI endpoint
middlebrick scan https://api.yourfastapp.com

The scanner tests for JWT vulnerabilities by attempting algorithm confusion attacks, checking for weak signature validation, and probing for endpoints that accept unsigned tokens.

Static Analysis Patterns

middleBrick's OpenAPI analysis identifies cryptographic issues in your FastAPI specification. For applications using FastAPI's auto-generated OpenAPI documentation, the scanner cross-references endpoint definitions with cryptographic requirements:

{
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  }
}

The scanner flags missing algorithm specifications, weak key lengths, and improper JWT configurations.

LLM-Specific Cryptographic Checks

For FastAPI applications serving LLM endpoints, middleBrick performs unique cryptographic assessments. Many FastAPI LLM applications expose system prompts or model configurations without proper authentication:

# Vulnerable FastAPI LLM endpoint
@app.get('/model/config')
async def get_model_config():
    return {
        'system_prompt': 'You are a helpful assistant...',
        'temperature': 0.7,
        'max_tokens': 4096
    }

middleBrick detects these endpoints and tests for prompt injection vulnerabilities that could lead to data exfiltration.

CI/CD Integration

middleBrick's GitHub Action allows FastAPI teams to catch cryptographic failures before deployment:

- name: middleBrick Security Scan
  uses: middleBrick/middleBrick-action@v1
  with:
    api_url: 'https://staging.yourfastapp.com'
    fail_below_score: 'B'
    token: ${{ secrets.MIDDLEBRICK_TOKEN }}

This integration ensures cryptographic regressions are caught in the development pipeline.

Fastapi-Specific Remediation

Remediating cryptographic failures in FastAPI requires both framework-specific solutions and general cryptographic best practices. Here are FastAPI-specific implementations:

Secure JWT Implementation

FastAPI's JWT handling should use strict algorithm validation and proper key management:

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError
from passlib.context import CryptContext
from datetime import datetime, timedelta

SECRET_KEY = os.getenv('SECRET_KEY', default=None)
ALGORITHM = 'HS256'
ACCESS_TOKEN_EXPIRE_MINUTES = 30

oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token')

# Use passlib for secure password hashing
pwd_context = CryptContext(schemes=['bcrypt'], deprecated='auto')

async def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({'exp': expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

async def verify_token(token: str = Depends(oauth2_scheme)):
    try:
        # Only allow the specified algorithm
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        return payload
    except JWTError:
        raise HTTPException(status_code=401, detail='Invalid authentication credentials')

This implementation uses a single, hardcoded algorithm and proper error handling.

Secure Secret Management

FastAPI applications should use environment variables with proper validation:

import os
from fastapi import FastAPI
from dotenv import load_dotenv

load_dotenv()

# Validate SECRET_KEY length
SECRET_KEY = os.getenv('SECRET_KEY')
if SECRET_KEY and len(SECRET_KEY) < 32:
    raise ValueError('SECRET_KEY must be at least 32 bytes')

app = FastAPI()

Using python-dotenv ensures secrets are loaded from environment files during development while requiring explicit environment variables in production.

Timing Attack Prevention

FastAPI's authentication should use constant-time comparisons:

from hmac import compare_digest

async def verify_password(plain_password: str, hashed_password: str) -> bool:
    return compare_digest(
        pwd_context.verify(plain_password, hashed_password),
        True
    )

The compare_digest function prevents timing attacks by ensuring comparison time is independent of input values.

Secure Random Token Generation

FastAPI applications should use cryptographically secure random number generation:

import secrets
from fastapi import FastAPI

app = FastAPI()

async def generate_secure_token():
    return secrets.token_urlsafe(32)  # 256-bit secure token

async def generate_verification_code():
    return secrets.randbelow(1000000)  # 6-digit code

The secrets module provides cryptographically strong random numbers suitable for security-sensitive operations.

Proper Key Length and Algorithm Selection

FastAPI's cryptographic operations should use appropriate key lengths:

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

# Generate 2048-bit RSA keys (minimum recommended)
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048
)

# Serialize keys securely
pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword')
)

Always use key sizes that meet current security standards—2048 bits for RSA, 256 bits for AES.

Frequently Asked Questions

How does middleBrick detect cryptographic failures in FastAPI applications?
middleBrick performs black-box scanning of your FastAPI endpoints, testing for weak JWT implementations, algorithm confusion vulnerabilities, and insufficient key lengths. The scanner actively probes endpoints with malformed tokens, attempts algorithm downgrade attacks, and checks for endpoints that accept unsigned tokens. It also analyzes your OpenAPI specification to identify cryptographic configurations that may be vulnerable.
Can middleBrick scan FastAPI applications that use OAuth2 or other authentication frameworks?