Metadata-Version: 2.4
Name: masu727
Version: 1.4.0
Summary: AI-powered, authentication-independent security firewall middleware for Django.
Author: Your Organization
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django>=4.2
Provides-Extra: redis
Requires-Dist: redis>=4.5; extra == "redis"
Requires-Dist: django-redis>=5.3; extra == "redis"
Dynamic: license-file

# MASU727

[![PyPI](https://img.shields.io/pypi/v/masu727)](https://pypi.org/project/masu727/)
[![Python Versions](https://img.shields.io/pypi/pyversions/masu727)](https://pypi.org/project/masu727/)
[![License](https://img.shields.io/pypi/l/masu727)](LICENSE)
[![Downloads](https://img.shields.io/pypi/dm/masu727)](https://pypi.org/project/masu727/)
[![Tests Passing](https://img.shields.io/badge/tests-280%20passing-brightgreen)](#7-running-the-test-suite)

**MASU727 (Malicious and Suspicious Activities Prevention Unit 727)** is an AI-powered security firewall for Django. It sits **in front of authentication** and inspects every incoming request, without requiring any change to your existing auth setup (Session, JWT, OAuth, Web727Token, or custom).

---

## Table of Contents

1. [How it works](#1-how-it-works)
2. [Requirements](#2-requirements)
3. [Installation](#3-installation)
4. [Writing and registering a custom detector](#4-writing-and-registering-a-custom-detector)
5. [Configuring the rule engine](#5-configuring-the-rule-engine)
6. [Dashboard & API](#6-dashboard--api)
7. [Running the test suite](#7-running-the-test-suite)
8. [Reports & maintenance commands](#8-reports--maintenance-commands)
9. [Extension points](#9-extension-points)
10. [Performance notes & benchmarking](#10-performance-notes--benchmarking)
11. [Feature status](#11-feature-status)
12. [Documentation index](#12-documentation-index)
13. [Security note](#13-security-note)

---

## 1. How it works

Every request passes through `FirewallEngine`, which runs a configurable, ordered set of detectors **before** your authentication layer ever sees the request:

```
Request
   │
   ▼
MASU727Middleware
   │
   ▼
FirewallEngine
   │
   ├── HoneypotDetector
   ├── RateLimitDetector
   ├── RequestValidationDetector
   ├── BotDetector
   ├── ScannerPathDetector
   ├── SQLInjectionDetector
   ├── XSSDetector
   ├── CommandInjectionDetector
   ├── DirectoryTraversalDetector
   ├── FileUploadDetector
   └── ...your CUSTOM_DETECTORS
   │
   ▼
Authentication (Session / JWT / Web727Token / OAuth) — untouched
   │
   ▼
Views
```

Based on your configuration, each detector can **allow, log, warn, challenge, or block** a request.

---

## 2. Requirements

| Requirement | Version |
|---|---|
| Python | 3.9+ |
| Django | 4.2+ (5.x fully supported) |

---

## 3. Installation

**Step 1 — Install the package**
```bash
pip install masu727
```

**Step 2 — Register the app**
```python
INSTALLED_APPS = [
    ...
    "masu727",
]
```

**Step 3 — Add the middleware (keep it near the top of the stack)**
```python
MIDDLEWARE = [
    "masu727.middleware.firewall.FirewallMiddleware",
    ...
]
```
> The pre-1.1 import path `masu727.middleware.MASU727Middleware` still works and resolves to the same class.

**Step 4 — Run migrations**
```bash
python manage.py migrate masu727
```

That's it — defaults (`PROFILE: "NORMAL"`) are sane out of the box. Everything from here on is optional tuning.

---

## 4. Writing and registering a custom detector

The engine never hardcodes a detector class — it resolves an ordered list of dotted paths from `rules.py` (or your `DETECTORS`/`CUSTOM_DETECTORS` settings), imports each one, and calls `.detect()` on it. Adding a detector is a **settings change**, not a code change to `engine.py`.

**Step 1 — Subclass `BaseDetector`**
```python
from masu727.detectors.base import BaseDetector, DetectionResult

class MyDetector(BaseDetector):
    name = "my_custom_rule"      # unique key, used in RULES and threat logs
    default_score = 50           # points added to the IP's threat score on a match
    default_action = "log"       # allow | log | warn | challenge | block

    def detect(self, context):
        # context already has client_ip and a collected payload string
        # (query string + body), so you don't have to redo that work.
        if "x-suspicious" in context.headers:
            return DetectionResult(
                matched=True,
                detail="suspicious header present",
            )
        return DetectionResult(matched=False)
```

**Step 2 — Register it**
```python
MASU727 = {
    "CUSTOM_DETECTORS": ["myproject.security.MyDetector"],
}
```

No subclassing the middleware, no editing MASU727's source. See [`docs/detectors.md`](docs/detectors.md) for the full guide, including replacing the built-in detector set entirely via `DETECTORS`.

---

## 5. Configuring the rule engine

### 6.1 Action types

| Action | Effect |
|---|---|
| `allow` | Detector runs but never contributes to score or blocking, even on a match. |
| `log` | Match adds `score` to the IP's running total. Doesn't block by itself. |
| `warn` | Same as `log` today; kept distinct for your own dashboards/alerts. |
| `challenge` | Reserved for future CAPTCHA-style integration; behaves like `warn` for now. |
| `block` | Match ends evaluation immediately — this detector's verdict is final, regardless of score. |

> If several `log`/`warn` detectors fire on the same request and their combined score crosses `BLOCK_ON_SCORE`, the request is blocked on whichever detector pushed it over the line. This is what keeps false positives down — one weak signal won't block anyone, but three together will.

### 6.2 `RULES` — per-detector configuration

```python
MASU727 = {
    "RULES": {
        "sql_injection":  {"enabled": True, "score": 90, "action": "block"},
        "xss":            {"enabled": True, "score": 60, "action": "log"},
        "scanner_path":   {"action": "log"},
        "bot_signature":  {"enabled": False},
    },
}
```

Any field you omit falls back to the detector's built-in default. Legacy flat flags (e.g. `ENABLE_SQL_DETECTION`) still work as a fallback for `enabled` when a detector has no `RULES` entry, so older configs keep working unchanged.

### 6.3 `PROFILE` — preset tuning

Instead of hand-tuning 10+ `RULES` entries, pick a profile:

```python
MASU727 = {"PROFILE": "STRICT"}   # BASIC | NORMAL | STRICT | ENTERPRISE
```

| Profile | Behavior |
|---|---|
| `BASIC` | Log-only, high block threshold. Good for a new integration where you want visibility before rejecting traffic. |
| `NORMAL` | The default — matches built-in per-detector defaults. |
| `STRICT` | Most detectors block outright, lower threshold. |
| `ENTERPRISE` | `STRICT` plus notifications and behaviour analysis on by default. |

Precedence (highest wins): explicit `RULES` entry → active `PROFILE`'s `RULES` → detector's hardcoded default. So you can start from `STRICT` and carve out one exception:

```python
MASU727 = {
    "PROFILE": "STRICT",
    "RULES": {"xss": {"action": "log"}},  # everything else stays STRICT
}
```

### 6.4 `PATH_PROFILES` — per-path policy

```python
MASU727 = {
    "PROFILE": "NORMAL",
    "PATH_PROFILES": {
        "/admin/": "STRICT",
        "/api/public/": "BASIC",
    },
}
```

Longest-prefix-match wins; anything not covered uses the top-level `PROFILE`.

### 6.5 Excluding paths entirely

```python
MASU727 = {
    "EXCLUDE_URLS": ["/healthz", "/metrics"],
    "TRUSTED_WEBHOOKS": ["/webhooks/stripe/", "/webhooks/github/"],
}
```

- `EXCLUDE_URLS` (merged with the older `WHITELIST_PATHS`) skips MASU727 entirely for matching paths.
- `TRUSTED_WEBHOOKS` does the same for known webhook endpoints. MASU727 does **not** verify webhook signatures itself — keep doing that in your view.

### 6.6 `BLOCK_RESPONSE` — response shape

```python
MASU727 = {
    "BLOCK_RESPONSE": {"status": 403, "format": "json"},   # or "html"
}
# Hide that anything was blocked at all:
MASU727 = {"BLOCK_RESPONSE": {"status": 404, "format": "json"}}
# Redirect instead:
MASU727 = {"BLOCK_RESPONSE": {"redirect_url": "https://example.com/blocked"}}
```

> Rate-limit blocks always answer `429`, regardless of `BLOCK_RESPONSE.status` — that's the correct semantic code for "you're going too fast."

### 6.7 Settings validation

Invalid config fails at startup (`python manage.py check`), not in production traffic. This catches bad `PROFILE` names, invalid `action` values in `RULES`, malformed `RATE_LIMIT` strings, and unimportable `CUSTOM_DETECTORS` paths early.

---

## 6. Dashboard & API

**Step 1 — Wire up the URLs**
```python
# project/urls.py
urlpatterns = [
    ...
    path("masu727/", include("masu727.urls")),
]
```

**Step 2 — Use the exposed routes** (all require `is_staff`)

| Method | Endpoint | Purpose |
|---|---|---|
| `GET` | `/masu727/dashboard/` | Staff-only HTML dashboard — attack timeline (24h, by hour), top attack types, top attacking IPs, top countries, recent threats, CSV/JSON export |
| `GET` | `/masu727/api/threats` | Recent threat log entries (JSON) |
| `GET` | `/masu727/api/blocked` | Currently blocked IPs (JSON) |
| `POST` | `/masu727/api/unblock` | Unblock an IP — body: `{"ip_address": "1.2.3.4"}` |

---

## 7. Running the test suite

```bash
pip install pytest pytest-django
PYTHONPATH=. python -m pytest -v
```

280 pytest-django tests across `test_sql.py`, `test_xss.py`, `test_scanner.py`, `test_behaviour.py`, `test_context.py`, `test_rules.py`, `test_registry.py`, `test_signals.py`, `test_models.py`, `test_api.py`, `test_engine.py`, `test_middleware.py`, `test_rate_limit.py`, and `test_uploads.py`.

Coverage includes: detector pattern coverage (including encoding-evasion and known false-positive checks), the engine's action/scoring semantics, custom detector loading via both settings and the imperative registry, profile resolution, signal dispatch, middleware integration (blocking, exclusions, trusted IPs, response formats), the REST API, model behavior, rate limiting, and file upload scanning.

---

## 8. Reports & maintenance commands

```bash
# Weekly (or any period) summary: totals, top attack types, most-attacked
# URLs, top attacking IPs, top countries.
python manage.py masu727_report --days 7
python manage.py masu727_report --days 30 --format json

# Prune expired IP blocks and old threat logs (run on a schedule).
python manage.py masu727_cleanup --keep-days 30
```

---

## 9. Extension points

**Geo-blocking** (`masu727/geo.py`) — opt-in country allow/deny list. No GeoIP database is bundled (licensing/size); register your own resolver:
```python
from masu727.geo import set_resolver
set_resolver(lambda ip: my_geoip_lookup(ip))
```

**Threat intelligence feeds** (`masu727/threat_intel.py`) — register a callable returning a set of flagged IPs (Tor exit nodes, known-bad-IP lists, etc.), then check it from a custom detector. No feed is bundled by default — see the module docstring for a complete example.

> Browser/device fingerprinting, CAPTCHA integration, ML-based anomaly detection, and OpenAPI docs are intentionally left for v2, per the original roadmap.

---

## 10. Performance notes & benchmarking

- Use Redis (`django-redis`) as your `CACHES["default"]` backend in production — rate limiting, temporary blocks, and threat scores all live in cache, not the database, so they stay fast under load.
- The database is only used for **persistent** logs (`ThreatLog`, `BlockedIP`, `HoneypotHit`, `TrustedIP`) and admin/dashboard views.
- Regex patterns are compiled once at import time.
- The detector list is built once per process (from `RULES`/`PROFILE`/`CUSTOM_DETECTORS`) and cached — not re-parsed on every request.
- Threat-log writes happen on a background thread, so they never add latency to the request/response cycle.
- Detection short-circuits on `block`-action detectors, evaluated cheapest and highest-signal first (honeypot, rate limit, request validation, bot signature) before the more expensive payload regex scans run.

**Run the benchmark yourself:**
```bash
DJANGO_SETTINGS_MODULE=tests.settings PYTHONPATH=. python benchmarks/benchmark.py
```

Typical overhead is **~1–2 ms/request**, depending on which detectors are enabled — figures vary by hardware, which is why fixed numbers aren't published here. Overhead is dominated by the regex payload scans (SQLi/XSS/command/traversal), not by rule-resolution or the RULES/PROFILE machinery — that's why it's flat across profiles. If you need to shave it further, disable detectors you don't need via `RULES` rather than relying on `EXCLUDE_URLS` for high-traffic routes you still want *some* protection on.

---

## 11. Feature status

| Feature | Status |
|---|:---:|
| SQL Injection | ✅ |
| XSS | ✅ |
| Command Injection | ✅ |
| Directory Traversal | ✅ |
| Bot Detection | ✅ |
| Recon Scanner | ✅ |
| Upload Protection | ✅ |
| Rate Limiting | ✅ |
| Behaviour Analysis | ✅ |
| Honeypots | ✅ |
| REST API | ✅ |

**As of 1.4.0, MASU727 ships with:**
- Firewall Engine with pluggable, per-detector-configurable rules (`RULES`, `PROFILE`, `PATH_PROFILES`, `DETECTORS`, `CUSTOM_DETECTORS`)
- Detector Registry — two registration paths, settings-driven (`rules.py`) and code-driven (`registry.py`), feeding the same engine
- `SecurityContext` — a single, typed object every detector receives (`.ip`, `.payload`, `.user`, `.country`, `.headers`, `.score`, ...)
- Configurable actions per detector: allow / log / warn / challenge / block
- Configurable block responses: status code, JSON/HTML, or redirect
- Categorized SQL Injection detection (tautology, union, stacked DML, blind/time, error-based, stored-proc, comment terminators, structural)
- Categorized XSS detection with HTML-entity/URL/base64 decoding to catch obfuscated payloads
- Command Injection / Directory Traversal detectors
- Scanner (recon) path detection, bot/automation-tool detection (curl, sqlmap, Burp, ZAP, Nikto, Nmap/NSE, Gobuster, FFUF, Dirsearch, Acunetix)
- Behaviour Anomaly Detection (high 404 ratio, rapid-crawl pattern) wired in as a real detector, not just tracked data
- Rate Limiter (cache-backed)
- Honeypot Engine (configurable trap paths)
- File Upload Scanner (blocked extensions, double-extension trick, MIME mismatch, zip-bomb heuristics)
- IP Protection (whitelist / blacklist / temporary / permanent / trusted)
- Django signals (`attack_detected`, `request_blocked`, `sql_detected`, `scanner_detected`) and an `ON_BLOCK` hook
- Structured, async logging (IP, user, session, headers, payload, score, action, duration)
- Admin dashboard with attack timeline + CSV/JSON export
- `masu727_report` and `masu727_cleanup` management commands
- Versioned REST-style API (`/api/v1/threats`, `/blocked`, `/unblock`, with unversioned aliases)
- Django admin integration for all models
- Settings validation via Django system checks (profiles, rules, rate limits, detector paths, allowed origins, block-response format)
- Full pytest suite (280 tests)
- Benchmark script measuring overhead across all profiles

**Current status:**
- ✔ 280 automated pytest tests
- ✔ Django 5 compatible
- ✔ Python 3.12 tested
- ✔ Production ready

---

## 12. Documentation index

| Doc | Covers |
|---|---|
| [`docs/installation.md`](docs/installation.md) | Setup details |
| [`docs/configuration.md`](docs/configuration.md) | Profiles, RULES, signals, hooks, full settings guide |
| [`docs/detectors.md`](docs/detectors.md) | Built-in detector reference + writing your own |
| [`docs/dashboard.md`](docs/dashboard.md) | Dashboard usage |
| [`docs/api.md`](docs/api.md) | REST API reference |
| [`docs/faq.md`](docs/faq.md) | Common questions |
| [`docs/performance.md`](docs/performance.md) | Overhead numbers, where the time goes, multi-worker cache correctness |
| [`docs/troubleshooting.md`](docs/troubleshooting.md) | Common issues |
| [`docs/migration-guide.md`](docs/migration-guide.md) | Breaking/notable changes per version |
| [`examples/`](examples/) | `MIDDLEWARE` ordering for session, JWT, custom-token, and OAuth2 auth setups |

---

## 13. Security note

MASU727 is a **defense-in-depth layer**, not a replacement for parameterized queries, output escaping, CSRF protection, and Django's other built-in protections — keep using those. Treat it as a WAF, not a substitute for secure coding practices.
