PrimeDefender security middleware for FastAPI: WAF-style detection, blocking, and incident reporting to the PrimeDefender bridge.
Project description
primedefender-fastapi
PrimeDefender adds a security layer to FastAPI applications: it inspects incoming requests for common attack patterns, optionally blocks them, and sends structured incidents to your PrimeDefender bridge (for example for a live monitoring map).
This package publishes to PyPI as primedefender-fastapi. The import name is primedefender_fastapi.
Features
| Detection | Notes |
|---|---|
| SQL injection | Signature-based |
| XSS | Signature-based |
| Brute force | Configurable window on auth paths |
| Path traversal | Signature-based |
| Command injection | Signature-based |
| File inclusion | Signature-based |
| DDoS / flood | Per-IP sliding window |
| Bot activity | User-agent heuristics + rate limit |
| Scanner | UA + path probes + rate limit |
| Suspicious request | Method / query / body heuristics (observe by default) |
| Auth bypass probe | Header / query patterns (observe by default) |
Blocked requests return JSON with HTTP 403 or 429 as appropriate. Incidents are POSTed to the bridge (default path /ingest if your PRIMEDEFENDER_BRIDGE_URL has no path).
Requirements
- Python 3.10+
- A running PrimeDefender bridge that accepts the incident JSON (see your dashboard docs).
Install
pip install primedefender-fastapi
For a local editable install while developing the package:
pip install -e ./primedefender-fastapi
Environment variables
Set these in your process environment or load them with python-dotenv before the app imports settings (see below).
| Variable | Required | Description |
|---|---|---|
PRIMEDEFENDER_BRIDGE_URL |
Yes* | Bridge base URL, e.g. http://localhost:3000 (path /ingest is added if missing) |
PRIMEDEFENDER_API_KEY |
Yes* | API key sent as X-Api-Key / Authorization: Bearer |
PRIMEDEFENDER_SITE_ID |
Yes* | Site identifier in payloads |
PRIMEDEFENDER_SITE_LAT |
Recommended | Target latitude for map “to” pin |
PRIMEDEFENDER_SITE_LON |
Recommended | Target longitude |
PRIMEDEFENDER_SITE_REGION_LABEL |
Optional | Human label, e.g. Indonesia, Bali → targetLabel = "{site_id} · {label}" |
PRIMEDEFENDER_PRIVATE_SOURCE_LABEL |
Optional | Label for private/loopback IPs |
PRIMEDEFENDER_AUTH_BYPASS_MODE |
Optional | observe (default) or block |
PRIMEDEFENDER_SUSPICIOUS_REQUEST_MODE |
Optional | observe (default) or block |
PRIMEDEFENDER_MAX_ENCODING_LAYERS |
Optional | Max nested percent-encoding depth allowed in query/body (default 3); deeper chains return 403 (excessive_encoding). Set 0 to disable. |
PRIMEDEFENDER_FLOOD_WINDOW_SECONDS |
Optional | Sliding window length in seconds for the global per-IP request rate (default 10). |
PRIMEDEFENDER_FLOOD_MAX_REQUESTS |
Optional | Max requests per IP per window before 429 / ddos detection (default 60). |
PRIMEDEFENDER_FLOOD_EXEMPT_PATHS |
Optional | Comma-separated paths not counted toward that limit. If unset, defaults to /health (for load-balancer probes). If set to an empty string, no paths are exempt. |
*If bridge URL, API key, or site id is missing, reporting is disabled (middleware still runs detections).
See .env.example in this repository for tuning knobs (PRIMEDEFENDER_BODY_CAP_BYTES, rate limits, GeoIP TTL, etc.).
FastAPI usage
Minimal (configuration only from environment):
from fastapi import FastAPI
from primedefender_fastapi import PrimeDefenderMiddleware
app = FastAPI()
app.add_middleware(PrimeDefenderMiddleware)
Load .env early so variables exist when settings are first read:
from pathlib import Path
from dotenv import load_dotenv
load_dotenv(Path(__file__).resolve().parent / ".env")
Optional constructor overrides (other fields still come from the environment):
app.add_middleware(
PrimeDefenderMiddleware,
site_label="Indonesia, Bali",
auth_bypass_mode="observe",
suspicious_request_mode="block",
)
Explicit settings object (e.g. tests or multi-tenant):
from primedefender_fastapi import PrimeDefenderMiddleware, PrimeDefenderSettings
settings = PrimeDefenderSettings.from_env()
app.add_middleware(PrimeDefenderMiddleware, settings=settings)
Connect to the PrimeDefender bridge
- Run your bridge (often on port
3000or behind HTTPS). - Set
PRIMEDEFENDER_BRIDGE_URLto that origin, e.g.http://localhost:3000. - Ensure the bridge exposes
POST /ingest(or set the full URL including path). - Use a valid
PRIMEDEFENDER_API_KEYaccepted by the bridge.
Health check (typical): GET http://localhost:3000/health.
Test SQLi / XSS locally
With the API on port 8000:
SQL injection (query)
curl "http://127.0.0.1:8000/auth/login?next=' OR 1=1 --"
XSS
curl "http://127.0.0.1:8000/?q=%3Cscript%3Ealert(1)%3C/script%3E"
Map labels (optional test headers)
curl "http://127.0.0.1:8000/auth/login?next=' OR 1=1 --" \
-H "X-Prime-Source-Lat: 34.6937" \
-H "X-Prime-Source-Lon: 135.5023" \
-H "X-Prime-Source-Label: Japan, Osaka"
Building and publishing
Uses hatchling (PEP 517):
pip install build
python -m build
Upload dist/* to PyPI with twine (use API tokens and trusted publishing in CI in production).
License
MIT — see LICENSE.
Repository
Placeholder links are set in pyproject.toml (Homepage / Repository). Replace with your real GitHub URL before publishing.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file primedefender_fastapi-0.1.5.tar.gz.
File metadata
- Download URL: primedefender_fastapi-0.1.5.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36350c559536f5b840bbb913908770ea036e943938571bb146baf883386dbc21
|
|
| MD5 |
2731b2ab45e5e45394f573694bebda44
|
|
| BLAKE2b-256 |
517aa2851d782cabc1af66b50fbfcf548482e36ac15234a8aa68588dd1c69876
|
File details
Details for the file primedefender_fastapi-0.1.5-py3-none-any.whl.
File metadata
- Download URL: primedefender_fastapi-0.1.5-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1f4a14ee30bda59dd6df48310fad86a0ae83fe8474f23fbbb5b1f30ddf2f2d7
|
|
| MD5 |
4d1081acd1835fd4b2bcdbe5cd2e5ea9
|
|
| BLAKE2b-256 |
c9336864e054d3a22429ea3b615ab53018f5a9cc54e25eed01026a0af4a0f523
|