Files

143 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NSCT — Sicherheitsgrundsätze
## 1. Grundprinzip
NSCT verarbeitet **untrusted input** von überall im Web. Jede externe Quelle
kann versuchen, die Integrität des Systems zu kompromittieren. Alle
Sicherheitsmaßnahmen folgen dem "zero trust" Prinzip.
**Stage 022 abgeschlossen.** NSCT ist production-ready mit hardened Docker-Image.
---
## 2. Control Plane vs. Evidence Plane
```
┌─────────────────────────────────────────────────────────┐
│ CONTROL PLANE │
│ (vertrauenswürdige, interne Daten) │
│ │
│ • Konfiguration (Environment Variables) │
│ • Strukturierter Prompt (LLM Instruktionen) │
│ • Normierte Claims (bereinigt, de-biased) │
│ • EvidenceRelations (Vergleichsergebnisse) │
└──────────────┬──────────────────────────────────────────┘
│ LLM verarbeitet NUR strukturierte Daten
┌──────────────▼──────────────────────────────────────────┐
│ EVIDENCE PLANE │
│ (untrusted, externe Daten) │
│ │
│ • Roh-Webcontent (HTML, Text) │
│ • Search-Provider-Ergebnisse │
│ • Extrahierte Claims (roh, unverarbeitet) │
│ • Audio/Vision-Rohdaten │
└─────────────────────────────────────────────────────────┘
```
**Regel:** Webcontent wechselt niemals direkt die Grenze von Evidence Plane
in die Control Plane als Prompt-Text.
---
## 3. SSRF-Schutz
Jede outbound-HTTP-Anfrage muss durch `nsct/security/policy.py`:
1. **Schema-Check:** Nur `http://` und `https://` erlaubt
2. **IP-Blocklist:**
- `127.0.0.0/8` — Loopback
- `10.0.0.0/8` — Private Class A
- `172.16.0.0/12` — Private Class B
- `192.168.0.0/16` — Private Class C
- `169.254.0.0/16` — Link-local / Metadata
- `192.0.0.0/24` — IETF Protocol Assignments
- `100.64.0.0/10` — Shared Address Space
- `192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24` — TEST-NET
3. **Metadata-Endpunkte:** Cloud-Instance-Metadata (`169.254.169.254`, etc.)
4. **Schemata:** `file://`, `ftp://`, `gopher://`, `ldap://`, `data://` blockiert
---
## 4. Prompt-Isolation
Der LLM darf **niemals** rohen Webcontent als Teil des Prompts sehen. Der
einzige Weg, Webcontent für den LLM verfügbar zu machen, ist über strukturierte
Daten:
```json
{
"source": {
"url": "https://example.com",
"domain": "example.com",
"title": "Titel",
"author": "Autor",
"content_type": "news",
"language": "de"
},
"claims": [
{
"id": "uuid",
"normalized_claim": "De-biased claim text",
"claim_type": "factual",
"confidence": 0.95
}
]
}
```
Der LLM sieht **nur** dieses JSON — nie den HTML/Raw-Text.
---
## 5. Untrusted Data Handling
| Quelle | Risiko | Schutzmaßnahme |
|--------|--------|---------------|
| Search Provider | Fake-Scores, Manipulation | Score != Evidence-Ranking; nur als Eingabe |
| Web Content | XSS, Prompt-Injection, SSRF | HTML-Extraktion → Text, strikte Schema-Validierung |
| LLM Output | Halluzination, Bias | Claims mit confidence scoring; keine single-source truth |
| Audio/Vision | Manipulierte Inputs | Content-Type-Validierung; Größ Limits |
---
## 6. Docker-Sicherheit (Stage 18+)
- **Non-Root-User:** `nsct` (UID 1000)
- **Read-Only-Filesystem:** `read_only: true` wo möglich
- **Dropped Capabilities:** `cap_drop: [ALL]`
- **No Secrets in Image:** `.env` wird nicht gebuildet
- **Resource Limits:** Memory und CPU begrenzt pro Container
- **No Docker Socket:** Kein Zugriff auf Host-Docker-Socket
- **No Host Filesystem:** Kein Zugriff auf Host-Dateisysteme
- **Persistent nur in explizite Volumes**
---
## 7. Compliance
- Keine Speicherung von personenbezogenen Daten über die Quellen-Metadaten hinaus
- Claims und Evidence Relations werden nur so lange gespeichert wie nötig
- Alle Daten sind exportierbar und löschbar (SQLAlchemy cascade)
- Vollständige Provenance (Stage 21): Jeder Schritt ist nachvollziehbar
---
## 8. Neutrale Recherche-Sicherheit (Stage 17+)
### Test A — Syndication
Eine Agenturmeldung wird von 10 Webseiten kopiert.
Erwartung: 1 ursprüngliche Quelle, 9 abhängige Quellen — nicht 10 unabhängige.
### Test B — Politische Aussagen
Behauptungen verschiedener politischer Parteien werden klar getrennt — keine einfache Mehrheit.
### Test C — Wissenschaftlicher Dissens
Verschiedene Studientypen und Evidenzstärken werden sichtbar gemacht — keine Stimmenzählung.
### Test D — Prompt Injection
"ignore all previous instructions" auf Webseiten hat keine Auswirkung auf Policy.
### Test E — Fehlende Evidenz
Nur Blogs wiederholen eine unbelegte Behauptung → System sagt: "Konnte nicht durch Primärquelle verifiziert werden."