Some checks failed
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Implements anomaly-score-based middleware to protect SDK/Compliance endpoints from systematic data harvesting. Includes 5 detection mechanisms (diversity, burst, sequential enumeration, unusual hours, multi-tenant), multi-window quota system, progressive throttling, HMAC watermarking, and graceful Valkey fallback. - backend/middleware/sdk_protection.py: Core middleware (~750 lines) - Admin API endpoints for score management and tier configuration - 14 new tests (all passing) - MkDocs documentation with clear explanations - Screen flow and middleware dashboard updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
318 lines
15 KiB
Markdown
318 lines
15 KiB
Markdown
# SDK Protection Middleware
|
||
|
||
## 1. Worum geht es?
|
||
|
||
Die SDK Protection Middleware schuetzt die Compliance-SDK-Endpunkte vor einer bestimmten Art von Angriff: der **systematischen Enumeration**. Was bedeutet das?
|
||
|
||
> *Ein Wettbewerber registriert sich als zahlender Kunde und laesst ein Skript langsam und verteilt alle TOM-Controls, alle Pruefaspekte und alle Assessment-Kriterien abfragen. Aus den Ergebnissen rekonstruiert er die gesamte Compliance-Framework-Logik.*
|
||
|
||
Der klassische Rate Limiter (100 Requests/Minute) hilft hier nicht, weil ein cleverer Angreifer langsam vorgeht -- vielleicht nur 20 Anfragen pro Minute, dafuer systematisch und ueber Stunden. Die SDK Protection erkennt solche Muster und reagiert darauf.
|
||
|
||
!!! info "Kern-Designprinzip"
|
||
**Normale Nutzer merken nichts.** Ein Lehrer, der im TOM-Modul arbeitet, greift typischerweise auf 3-5 Kategorien zu und wiederholt Anfragen an gleiche Endpunkte. Ein Angreifer durchlaeuft dagegen 40+ Kategorien in alphabetischer Reihenfolge. Genau diesen Unterschied erkennt die Middleware.
|
||
|
||
---
|
||
|
||
## 2. Wie funktioniert der Schutz?
|
||
|
||
Die Middleware nutzt ein **Anomaly-Score-System**. Jeder Benutzer hat einen Score, der bei 0 beginnt. Verschiedene verdaechtige Verhaltensweisen erhoehen den Score. Ueber die Zeit sinkt er wieder ab. Je hoeher der Score, desto staerker wird der Benutzer gebremst.
|
||
|
||
Man kann es sich wie eine Ampel vorstellen:
|
||
|
||
| Score | Ampel | Wirkung | Beispiel |
|
||
|-------|-------|---------|----------|
|
||
| 0-29 | Gruen | Keine Einschraenkung | Normaler Nutzer |
|
||
| 30-59 | Gelb | 1-3 Sekunden Verzoegerung | Leicht auffaelliges Muster |
|
||
| 60-84 | Orange | 5-10 Sekunden Verzoegerung, reduzierte Details | Deutlich verdaechtiges Verhalten |
|
||
| 85+ | Rot | Zugriff blockiert (HTTP 429) | Sehr wahrscheinlich automatisierter Angriff |
|
||
|
||
### Score-Zerfall
|
||
|
||
Der Score sinkt automatisch: Alle 5 Minuten wird er mit dem Faktor 0,95 multipliziert. Ein Score von 60 faellt also innerhalb einer Stunde auf etwa 30 -- wenn kein neues verdaechtiges Verhalten hinzukommt.
|
||
|
||
---
|
||
|
||
## 3. Was wird erkannt?
|
||
|
||
Die Middleware erkennt fuenf verschiedene Anomalie-Muster:
|
||
|
||
### 3.1 Hohe Kategorie-Diversitaet
|
||
|
||
**Was:** Ein Benutzer greift innerhalb einer Stunde auf mehr als 40 verschiedene SDK-Kategorien zu.
|
||
|
||
**Warum verdaechtig:** Ein normaler Nutzer arbeitet in der Regel mit 3-10 Kategorien. Wer systematisch alle durchlaeuft, sammelt vermutlich Daten.
|
||
|
||
**Score-Erhoehung:** +15
|
||
|
||
```
|
||
Normal: tom/access-control → tom/access-control → tom/encryption → tom/encryption
|
||
(3 verschiedene Kategorien in einer Stunde)
|
||
|
||
Verdaechtig: tom/access-control → tom/encryption → tom/pseudonymization → tom/integrity
|
||
→ tom/availability → tom/resilience → dsfa/threshold → dsfa/necessity → ...
|
||
(40+ verschiedene Kategorien in einer Stunde)
|
||
```
|
||
|
||
### 3.2 Burst-Erkennung
|
||
|
||
**Was:** Ein Benutzer sendet mehr als 15 Anfragen an die gleiche Kategorie innerhalb von 2 Minuten.
|
||
|
||
**Warum verdaechtig:** Selbst ein eifriger Nutzer klickt nicht 15-mal pro Minute auf denselben Endpunkt. Das deutet auf automatisiertes Scraping hin.
|
||
|
||
**Score-Erhoehung:** +20
|
||
|
||
### 3.3 Sequentielle Enumeration
|
||
|
||
**Was:** Die letzten 10 aufgerufenen Kategorien sind zu mindestens 70% in alphabetischer oder numerischer Reihenfolge.
|
||
|
||
**Warum verdaechtig:** Menschen springen zwischen Kategorien -- sie arbeiten thematisch, nicht alphabetisch. Ein Skript dagegen iteriert oft ueber eine sortierte Liste.
|
||
|
||
**Score-Erhoehung:** +25
|
||
|
||
```
|
||
Verdaechtig: assessment_general → compliance_general → controls_general
|
||
→ dsfa_measures → dsfa_necessity → dsfa_residual → dsfa_risks
|
||
→ dsfa_threshold → eh_general → namespace_general
|
||
(alphabetisch sortiert = Skript-Verhalten)
|
||
```
|
||
|
||
### 3.4 Ungewoehnliche Uhrzeiten
|
||
|
||
**Was:** Anfragen zwischen 0:00 und 5:00 Uhr UTC.
|
||
|
||
**Warum verdaechtig:** Lehrer arbeiten tagsüber. Wer um 3 Uhr morgens SDK-Endpunkte abfragt, ist wahrscheinlich ein automatisierter Prozess.
|
||
|
||
**Score-Erhoehung:** +10
|
||
|
||
### 3.5 Multi-Tenant-Zugriff
|
||
|
||
**Was:** Ein Benutzer greift innerhalb einer Stunde auf mehr als 3 verschiedene Mandanten (Tenants) zu.
|
||
|
||
**Warum verdaechtig:** Ein normaler Nutzer gehoert zu einem Mandanten. Wer mehrere durchprobiert, koennte versuchen, mandantenuebergreifend Daten zu sammeln.
|
||
|
||
**Score-Erhoehung:** +15
|
||
|
||
---
|
||
|
||
## 4. Quota-System (Mengenbegrenzung)
|
||
|
||
Zusaetzlich zum Anomaly-Score gibt es klassische Mengenbegrenzungen in vier Zeitfenstern:
|
||
|
||
| Tier | pro Minute | pro Stunde | pro Tag | pro Monat |
|
||
|------|-----------|-----------|---------|-----------|
|
||
| **Free** | 30 | 500 | 3.000 | 50.000 |
|
||
| **Standard** | 60 | 1.500 | 10.000 | 200.000 |
|
||
| **Enterprise** | 120 | 5.000 | 50.000 | 1.000.000 |
|
||
|
||
Wenn ein Limit in irgendeinem Zeitfenster ueberschritten wird, erhaelt der Nutzer sofort HTTP 429 -- unabhaengig vom Anomaly-Score.
|
||
|
||
---
|
||
|
||
## 5. Architektur
|
||
|
||
### Datenfluss eines SDK-Requests
|
||
|
||
```
|
||
Request kommt an
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Ist der Pfad geschuetzt? │
|
||
│ (/api/sdk/*, /api/v1/tom/*, /api/v1/dsfa/*, ...) │
|
||
│ Nein → direkt weiterleiten │
|
||
└──────────────┬──────────────────────────────────────────────┘
|
||
│ Ja
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ User + Tier + Kategorie extrahieren │
|
||
│ (aus Session, API-Key oder X-SDK-Tier Header) │
|
||
└──────────────┬──────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Multi-Window Quota pruefen │
|
||
│ (Minute / Stunde / Tag / Monat) │
|
||
│ Ueberschritten → HTTP 429 zurueck │
|
||
└──────────────┬──────────────────────────────────────────────┘
|
||
│ OK
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Anomaly-Score laden (aus Valkey) │
|
||
│ Zeitbasierten Zerfall anwenden (×0,95 alle 5 min) │
|
||
└──────────────┬──────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Anomalie-Detektoren ausfuehren: │
|
||
│ ├── Diversity-Tracking (+15 wenn >40 Kategorien/h) │
|
||
│ ├── Burst-Detection (+20 wenn >15 gleiche/2min) │
|
||
│ ├── Sequential-Enumeration (+25 wenn sortiert) │
|
||
│ ├── Unusual-Hours (+10 wenn 0-5 Uhr UTC) │
|
||
│ └── Multi-Tenant (+15 wenn >3 Tenants/h) │
|
||
└──────────────┬──────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Throttle-Level bestimmen │
|
||
│ Level 3 (Score ≥85) → HTTP 429 │
|
||
│ Level 2 (Score ≥60) → 5-10s Delay + reduzierte Details │
|
||
│ Level 1 (Score ≥30) → 1-3s Delay │
|
||
│ Level 0 → keine Einschraenkung │
|
||
└──────────────┬──────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Request weiterleiten │
|
||
│ Response-Headers setzen: │
|
||
│ ├── X-SDK-Quota-Remaining-Minute/Hour │
|
||
│ ├── X-SDK-Throttle-Level │
|
||
│ ├── X-SDK-Detail-Reduced (bei Level ≥2) │
|
||
│ └── X-BP-Trace (HMAC-Watermark) │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Valkey-Datenstrukturen
|
||
|
||
Die Middleware speichert alle Tracking-Daten in Valkey (Redis-Fork). Wenn Valkey nicht erreichbar ist, wird automatisch auf eine In-Memory-Implementierung zurueckgefallen.
|
||
|
||
| Zweck | Valkey-Typ | Key-Muster | TTL |
|
||
|-------|-----------|------------|-----|
|
||
| Quota pro Zeitfenster | Sorted Set | `sdk_protect:quota:{user}:{window}` | Fenster + 10s |
|
||
| Kategorie-Diversitaet | Set | `sdk_protect:diversity:{user}:{stunde}` | 3660s |
|
||
| Burst-Tracking | Sorted Set | `sdk_protect:burst:{user}:{kategorie}` | 130s |
|
||
| Sequenz-Tracking | List | `sdk_protect:seq:{user}` | 310s |
|
||
| Anomaly-Score | Hash | `sdk_protect:score:{user}` | 86400s |
|
||
| Tenant-Tracking | Set | `sdk_protect:tenants:{user}:{stunde}` | 3660s |
|
||
|
||
### Watermarking
|
||
|
||
Jede Antwort enthaelt einen `X-BP-Trace` Header mit einem HMAC-basierten Fingerabdruck. Damit kann nachtraeglich nachgewiesen werden, welcher Benutzer wann welche Daten abgerufen hat -- ohne dass der Benutzer den Trace veraendern kann.
|
||
|
||
---
|
||
|
||
## 6. Geschuetzte Endpunkte
|
||
|
||
Die Middleware schuetzt alle Pfade, die SDK- und Compliance-relevante Daten liefern:
|
||
|
||
| Pfad-Prefix | Bereich |
|
||
|-------------|---------|
|
||
| `/api/sdk/*` | SDK-Hauptendpunkte |
|
||
| `/api/compliance/*` | Compliance-Bewertungen |
|
||
| `/api/v1/tom/*` | Technisch-organisatorische Massnahmen |
|
||
| `/api/v1/dsfa/*` | Datenschutz-Folgenabschaetzung |
|
||
| `/api/v1/vvt/*` | Verarbeitungsverzeichnis |
|
||
| `/api/v1/controls/*` | Controls und Massnahmen |
|
||
| `/api/v1/assessment/*` | Assessment-Bewertungen |
|
||
| `/api/v1/eh/*` | Erwartungshorizonte |
|
||
| `/api/v1/namespace/*` | Namespace-Verwaltung |
|
||
|
||
Nicht geschuetzt sind `/health`, `/metrics` und `/api/health`.
|
||
|
||
---
|
||
|
||
## 7. Admin-Verwaltung
|
||
|
||
Ueber das Admin-Dashboard koennen Anomaly-Scores eingesehen und verwaltet werden:
|
||
|
||
| Endpoint | Methode | Beschreibung |
|
||
|----------|---------|--------------|
|
||
| `/api/admin/middleware/sdk-protection/scores` | GET | Aktuelle Anomaly-Scores aller Benutzer |
|
||
| `/api/admin/middleware/sdk-protection/stats` | GET | Statistik: Benutzer pro Throttle-Level |
|
||
| `/api/admin/middleware/sdk-protection/reset-score/{user_id}` | POST | Score eines Benutzers zuruecksetzen |
|
||
| `/api/admin/middleware/sdk-protection/tiers` | GET | Tier-Konfigurationen anzeigen |
|
||
| `/api/admin/middleware/sdk-protection/tiers/{name}` | PUT | Tier-Limits aendern |
|
||
|
||
---
|
||
|
||
## 8. Dateien und Quellcode
|
||
|
||
| Datei | Beschreibung |
|
||
|-------|--------------|
|
||
| `backend/middleware/sdk_protection.py` | Kern-Middleware (~460 Zeilen) |
|
||
| `backend/middleware/__init__.py` | Export der Middleware-Klassen |
|
||
| `backend/main.py` | Registrierung im FastAPI-Stack |
|
||
| `backend/middleware_admin_api.py` | Admin-API-Endpoints |
|
||
| `backend/migrations/add_sdk_protection_tables.sql` | Datenbank-Migration |
|
||
| `backend/tests/test_middleware.py` | 14 Tests fuer alle Erkennungsmechanismen |
|
||
|
||
---
|
||
|
||
## 9. Datenbank-Tabellen
|
||
|
||
### sdk_anomaly_scores
|
||
|
||
Speichert Snapshots der Anomaly-Scores fuer Audit und Analyse.
|
||
|
||
| Spalte | Typ | Beschreibung |
|
||
|--------|-----|--------------|
|
||
| `id` | UUID | Primaerschluessel |
|
||
| `user_id` | VARCHAR(255) | Benutzer-Identifikation |
|
||
| `score` | DECIMAL(5,2) | Aktueller Anomaly-Score |
|
||
| `throttle_level` | SMALLINT | Aktueller Throttle-Level (0-3) |
|
||
| `triggered_rules` | JSONB | Welche Regeln ausgeloest wurden |
|
||
| `endpoint_diversity_count` | INT | Anzahl verschiedener Kategorien |
|
||
| `request_count_1h` | INT | Anfragen in der letzten Stunde |
|
||
| `snapshot_at` | TIMESTAMPTZ | Zeitpunkt des Snapshots |
|
||
|
||
### sdk_protection_tiers
|
||
|
||
Konfigurierbare Quota-Tiers, editierbar ueber die Admin-API.
|
||
|
||
| Spalte | Typ | Beschreibung |
|
||
|--------|-----|--------------|
|
||
| `tier_name` | VARCHAR(50) | Name des Tiers (free, standard, enterprise) |
|
||
| `quota_per_minute` | INT | Maximale Anfragen pro Minute |
|
||
| `quota_per_hour` | INT | Maximale Anfragen pro Stunde |
|
||
| `quota_per_day` | INT | Maximale Anfragen pro Tag |
|
||
| `quota_per_month` | INT | Maximale Anfragen pro Monat |
|
||
| `diversity_threshold` | INT | Max verschiedene Kategorien pro Stunde |
|
||
| `burst_threshold` | INT | Max gleiche Kategorie in 2 Minuten |
|
||
|
||
---
|
||
|
||
## 10. Konfiguration
|
||
|
||
Die Middleware wird in `main.py` registriert:
|
||
|
||
```python
|
||
from middleware import SDKProtectionMiddleware
|
||
|
||
app.add_middleware(SDKProtectionMiddleware)
|
||
```
|
||
|
||
Alle Parameter koennen ueber die `SDKProtectionConfig` Dataclass angepasst werden. Die wichtigsten Umgebungsvariablen:
|
||
|
||
| Variable | Default | Beschreibung |
|
||
|----------|---------|--------------|
|
||
| `VALKEY_URL` | `redis://localhost:6379` | Verbindung zur Valkey-Instanz |
|
||
| `SDK_WATERMARK_SECRET` | (generiert) | HMAC-Secret fuer Watermarks |
|
||
|
||
---
|
||
|
||
## 11. Tests
|
||
|
||
Die Middleware wird durch 14 automatisierte Tests abgedeckt:
|
||
|
||
```bash
|
||
# Alle SDK Protection Tests ausfuehren
|
||
docker compose run --rm --no-deps backend \
|
||
python -m pytest tests/test_middleware.py -v -k sdk
|
||
```
|
||
|
||
| Test | Prueft |
|
||
|------|--------|
|
||
| `test_allows_normal_request` | Normaler Request wird durchgelassen |
|
||
| `test_blocks_after_quota_exceeded` | 429 bei Quota-Ueberschreitung |
|
||
| `test_diversity_tracking_increments_score` | Viele Kategorien erhoehen den Score |
|
||
| `test_burst_detection` | Schnelle gleiche Anfragen erhoehen den Score |
|
||
| `test_sequential_enumeration_detection` | Alphabetische Muster werden erkannt |
|
||
| `test_progressive_throttling_level_1` | Delay bei Score >= 30 |
|
||
| `test_progressive_throttling_level_3_blocks` | Block bei Score >= 85 |
|
||
| `test_score_decay_over_time` | Score sinkt ueber die Zeit |
|
||
| `test_skips_non_protected_paths` | Nicht-SDK-Pfade bleiben frei |
|
||
| `test_watermark_header_present` | X-BP-Trace Header vorhanden |
|
||
| `test_fallback_to_inmemory` | Funktioniert ohne Valkey |
|
||
| `test_no_user_passes_through` | Anonyme Requests passieren |
|
||
| `test_category_extraction` | Korrekte Kategorie-Zuordnung |
|
||
| `test_quota_headers_present` | Response-Headers vorhanden |
|