Metadata-Version: 2.4
Name: primedefender-fastapi
Version: 0.1.4
Summary: PrimeDefender security middleware for FastAPI: WAF-style detection, blocking, and incident reporting to the PrimeDefender bridge.
Project-URL: Homepage, https://github.com/primedefender/primedefender-fastapi
Project-URL: Repository, https://github.com/primedefender/primedefender-fastapi
Project-URL: Issues, https://github.com/primedefender/primedefender-fastapi/issues
Author: PrimeDefender contributors
License-Expression: MIT
License-File: LICENSE
Keywords: fastapi,intrusion-detection,middleware,primedefender,security,sqli,waf,xss
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Security
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: fastapi>=0.100.0
Requires-Dist: httpx>=0.25.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# primedefender-fastapi

**PrimeDefender** adds a security layer to [FastAPI](https://fastapi.tiangolo.com/) 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 **POST**ed 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

```bash
pip install primedefender-fastapi
```

For a local editable install while developing the package:

```bash
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):

```python
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:

```python
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):

```python
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):

```python
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)**

```bash
curl "http://127.0.0.1:8000/auth/login?next=' OR 1=1 --"
```

**XSS**

```bash
curl "http://127.0.0.1:8000/?q=%3Cscript%3Ealert(1)%3C/script%3E"
```

**Map labels (optional test headers)**

```bash
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):

```bash
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.
