Metadata-Version: 2.4
Name: primedefender-fastapi
Version: 0.1.7
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: MIT License
        
        Copyright (c) 2026 PrimeDefender contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
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.
