Skip to main content

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

  1. Run your bridge (often on port 3000 or behind HTTPS).
  2. Set PRIMEDEFENDER_BRIDGE_URL to that origin, e.g. http://localhost:3000.
  3. Ensure the bridge exposes POST /ingest (or set the full URL including path).
  4. Use a valid PRIMEDEFENDER_API_KEY accepted 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.

Release files for primedefender-fastapi 0.1.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for primedefender-fastapi 0.1.9
File Size Uploaded
primedefender_fastapi-0.1.9.tar.gz 27.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for primedefender-fastapi 0.1.9
File Interpreter ABI Platform
primedefender_fastapi-0.1.9-py3-none-any.whl Python 3 none any Details

Total release size: 60.3 kB

Release files / primedefender_fastapi-0.1.9.tar.gz

Download URL primedefender_fastapi-0.1.9.tar.gz
Size 27.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f4a0c27fe01dfbb1ef54eb66a9e773c263048c4ddfa32d364939e050639b37cb
BLAKE2b-256 checksum
How to use checksums
02aee786dc14432a3aab18300e71b3077c9258952c670151dd38071b88771ad2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / primedefender_fastapi-0.1.9-py3-none-any.whl

Download URL primedefender_fastapi-0.1.9-py3-none-any.whl
Size 32.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eaf028b99f59fdd72b0ae6cbceeda5793f164aef976d2ed01ae8e97fcd0f1189
BLAKE2b-256 checksum
How to use checksums
b662441d313937bbbc30aa263faeea9b0f40b7eb06ac9250d6be20ba4ab99fc6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.1.9 This release

2 release files

0.1.7

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page