Assessor_2.0/SECURITY.md

160 lines
9.9 KiB
Markdown

# Sicherheitsmodell
## Lokale Datenverarbeitung
ASSESSOR besitzt zwei kontrollierte lokale Betriebsarten:
1. Im empfohlenen Browserbetrieb liefert das lokale Node.js-Backend die React-App
und `/api/v1` vom selben Ursprung aus. Dateien werden ausschließlich an diesen
lokalen Ursprung übertragen und dort verarbeitet.
2. Im Vite-Entwicklungs- oder optionalen Tauri-Modus bleibt der vorhandene
Browserparser als Fallback aktiv.
Es gibt keinen Upload von Importdateien an externe Dienste und keine Telemetrie.
Die einzige freigegebene externe Anwendungs-API ist die unten beschriebene,
manuell ausgelöste NVD-CVE-Anreicherung. Das lokale Backend bindet standardmäßig nur an `127.0.0.1`.
Eine Freigabe im Firmennetz ist erst mit HTTPS, Authentifizierung und
Berechtigungen in Phase 14 zulässig.
CSV, JSON, XML, HTML und Excel werden über dieselbe plattformneutrale
Importengine verarbeitet. Im Backend stellt jsdom die lokale HTML-/XML-
Dokumentstruktur bereit. Skriptausführung ist nicht aktiviert; aktive
HTML-Elemente werden vor der Tabellenauswertung entfernt. Umfangreiche oder tief verschachtelte HTML-Berichte verwenden automatisch eine begrenzte, nicht rekursive Tabellenextraktion. Excel-Formeln werden
nicht ausgewertet; verschlüsselte Archive und eingebettete VBA-Projekte werden abgewiesen. Spreadsheet-orientierte CSV-Exporte neutralisieren formelaktive Zellanfänge.
### Verweisziele aus Berichten
Berichte führen fachlich notwendige Belegstellen als Verweise mit (Purple
Knight: Abschnitt „References"; PingCastle: Dokumentationslisten). Das Attribut
`href` wurde bis zur Freigabe vom 2026-07-26 pauschal entfernt, wodurch diese
Belegstellen verlorengingen.
Seither gilt eine engere Regel statt einer pauschalen Entfernung:
- Erhalten bleibt `href` **ausschließlich an einem Anker** und **ausschließlich
als `http:`- oder `https:`-Adresse** ohne Leerzeichen, Anführungszeichen oder
spitze Klammern.
- Jedes andere Schema (`javascript:`, `data:`, `file:`, `vbscript:` und alle
weiteren) sowie `xlink:href` werden weiterhin entfernt und gezählt.
- Alle übrigen aktiven Attribute (`on*`, `src`, `srcdoc`, `action`,
`formaction`) und aktiven Elemente werden unverändert entfernt.
- Der übernommene Wert wird normalisiert neu geschrieben und maskiert; Textinhalt
von Zellen mit Verweisen wird ebenfalls maskiert, damit ein Bericht kein
eigenes Markup einschleusen kann.
- Excel führt Verweisziele nicht im Zelltext, sondern als Eigenschaft der Zelle.
Sie unterliegen derselben Prüfung. Das Format kennt höchstens ein Ziel je
Zelle.
- Die Darstellung prüft in `RichTextValue.safeHref` ein zweites Mal und rendert
Verweise ausschließlich mit `target="_blank"` und `rel="noopener noreferrer"`.
Regressionen: `tests/importers/html-importer.test.ts` (Web-Adresse bleibt,
`javascript:`, `data:` und `file:` verschwinden, eingeschleustes Markup wird
maskiert), `tests/importers/excel-importer.test.ts` (Zellverweis wird
übernommen, Skriptschema nicht), `tests/server/node-import-engine.test.ts`
(Ereignisattribute fallen weiterhin heraus).
## API-Sicherheitsgrenze
- Alle Endpunkte sind unter `/api/v1` versioniert.
- Browser-App und API werden vom gleichen Ursprung ausgeliefert; der Server setzt
keine CORS-Freigabe.
- Schreibzugriffe verlangen `X-Assessor-Request: 1` und weisen fremde
`Origin`-Header ab.
- Antworten setzen CSP, `nosniff`, `DENY` für Frames, `no-referrer` und eine
Same-Origin-Ressourcenrichtlinie.
- API-Fehler enthalten eine Request-ID, aber keine internen Stacktraces.
- Das Audit-Log speichert nur Zeitpunkt, Methode, Pfad, Status, Dauer, Request-ID und gegebenenfalls einen Fehlercode, niemals Datei- oder JSON-Inhalte.
- Quelldateien sind auf 100 MiB begrenzt; Base64-JSON-Anfragen auf 140 MiB und Importstapel auf 50 Dateien. Tabellen-, Zeilen-, Spalten-, Zell-, Markup-, JSON- und ZIP-Grenzen werden vor und nach dem formatspezifischen Parsing geprüft.
- Der Server verarbeitet Parseraufträge in isolierten Workern mit standardmäßig 30 Sekunden Laufzeit, 512 MiB Old-Generation-Speicher, zwei parallelen Aufträgen sowie einer begrenzten Warteschlange.
- Dateiendung, deklarierte Größe, Base64-Form und tatsächliche Byteanzahl werden
vor dem Parsing geprüft. Große Base64-Zeichenfolgen werden iterativ validiert,
damit die API-Prüfung selbst keinen JavaScript-Stacküberlauf erzeugt.
### Externe NVD-CVE-Anreicherung
- Ein Import löst niemals selbst einen externen Netzwerkzugriff aus. Die
Anreicherung wird je bereits gespeichertem Defender-for-IoT-CVE bewusst über
`POST /api/v1/cves/:cveId/enrich` gestartet.
- Nur das Backend verbindet sich mit dem fest codierten Ursprung
`https://services.nvd.nist.gov/rest/json/cves/2.0`; die Browser-App bleibt auf
der Same-Origin-API. Benutzerkontrollierte Ziel-URLs werden nicht abgerufen.
- Zulässig sind ausschließlich normalisierte CVE-IDs. Vor dem Abruf muss die ID
von einem gespeicherten Defender-for-IoT-Finding referenziert werden, sodass
der Endpunkt nicht als allgemeiner externer Proxy verwendet werden kann.
- Antworten besitzen ein 8-MiB-Limit und ein konfigurierbares Timeout. Es werden
nur normalisierte öffentliche CVE-Felder gespeichert; optionale NVD-API-Keys
kommen ausschließlich aus `NVD_API_KEY`, werden nicht persistiert,
zurückgegeben oder protokolliert.
- Von NVD gelieferte Referenzziele gelten als nicht vertrauenswürdig. Es werden
nur `http:`/`https:`-Adressen übernommen und mit `target="_blank"` sowie
`rel="noreferrer"` gerendert.
## Batchimport-Grenze
Mehrdateiimporte verwenden eine serverseitige Vorschau mit eindeutiger Batch- und Eintrags-ID. Der Abschluss enthält nur die ausgewählten IDs, SHA-256-Werte und Dateimetadaten; das Backend gleicht sie gegen die von ihm selbst geparste Vorschau ab. Geänderte, unbekannte, verdrängte oder nach 15 Minuten beziehungsweise einem Neustart abgelaufene Auswahlen werden vor jeder Persistenz abgewiesen. Der Vorschaucache ist zusätzlich auf 10 Batches und 256 MiB Quelldaten begrenzt.
Maximal 50 Dateien werden pro Vorschau akzeptiert. Jede Datei wird unabhängig verarbeitet, damit ein Parserfehler kontrolliert als einzelne Fehlerzeile erscheint. Erst die bestätigte Auswahl wird in ein kanonisches Modell überführt. Projekt, Assessment, Scan-Lauf, Dateien, Tabellen, Findings, Evidenz, Diagnosen und Fingerprint-Historie werden gemeinsam in einer Repository- beziehungsweise PostgreSQL-Transaktion gespeichert.
SHA-256 wird aus den tatsächlichen Bytes berechnet. Die Datenbank speichert nur Fingerabdruck und Metadaten, nicht noch einmal den Dateiinhalt. Im Browserfallback liegt diese Historie nur im lokalen Browser-Speicher und ist daher keine Mehrbenutzersicherheits- oder Persistenzgarantie.
## PostgreSQL-Grenze
Ist `ASSESSOR_DATABASE_URL` gesetzt, verwendet das Backend PostgreSQL. Ohne URL
läuft der ausdrückliche In-Memory-Entwicklungsmodus. Eine konfigurierte, aber
nicht erreichbare Datenbank verursacht einen Startfehler; es gibt keinen stillen
Fallback mit möglichem Datenverlust.
- SQL-Werte werden ausschließlich über PostgreSQL-Parameter übergeben.
- Fremdschlüssel, Checks und Eindeutigkeitsregeln sichern Beziehungen zusätzlich
zum kanonischen Modellvalidator.
- Ein Import verwendet genau eine Poolverbindung und eine Datenbanktransaktion.
- Die globale Repository-Revision wird `FOR UPDATE` gesperrt und verhindert das
Überschreiben zwischenzeitlicher Änderungen.
- Migrationen werden per Advisory-Lock serialisiert, transaktional ausgeführt und
mit SHA-256-Prüfsumme protokolliert.
- Bereits angewandte Migrationen dürfen nicht verändert werden.
- Die Docker-Entwicklungsdatenbank veröffentlicht PostgreSQL nur auf
`127.0.0.1`.
- TLS darf nur für lokale Loopback-Ziele deaktiviert werden. Für entfernte
Datenbankziele ist TLS standardmäßig erforderlich.
- Datenbank-URLs und Passwörter werden nicht protokolliert und `.env.postgres`
wird nicht versioniert.
Originaldateien werden aktuell nicht als separate Serverartefakte aufbewahrt.
Das kanonische Modell kann eine Quelle ausdrücklich als eingebettet, extern oder
nicht aufbewahrt kennzeichnen. Backupdateien benötigen gesonderten Zugriffsschutz
und ein in Phase 14 festzulegendes Aufbewahrungs- und Löschkonzept.
## Tauri-Grenzen
- Die Desktop-Capability enthält ausschließlich `core:default`.
- Die Produktions-CSP erlaubt keine Verbindung zum Vite-Entwicklungsserver.
- HTTP-, WebSocket-, Shell- und Dateisystem-Plugins sind nicht aktiviert.
- Tauri bleibt eine optionale Hülle und enthält keine neue Fachlogik.
## Abhängigkeiten
`xlsx@0.18.5` bleibt wegen der bestehenden Kompatibilitätsanforderung vorerst
gebunden und wird lokal mit deaktivierter Formel- und VBA-Verarbeitung
eingesetzt. jsdom wird ausschließlich als lokaler, nicht skriptausführender
Markupadapter verwendet. `pg@8.22.0` stellt den parametrierten PostgreSQL-Pool
bereit. `npm audit` und `npm audit --omit=dev` melden im verifizierten
Abschlussstand keine bekannten Schwachstellen. Nicht vertrauenswürdige Dateien
bleiben unabhängig davon eine Eingabegrenze.
## Regressionstests
`npm test` führt Modul-, Server-, Parser-, API-, Migrations- und
Repositorytests sowie `tests/local-only-check.mjs` aus. Die Architekturprüfung
erlaubt Browser-`fetch` nur im gekapselten Same-Origin-API-Client und den
freigegebenen Backend-NVD-Client nur mit festem NIST-Ursprung; sie verhindert
CORS-Freigaben, zusätzliche Netzwerkpfade,
externe Assets, erweiterte Tauri-Rechte und Datenbankzugriffe aus React-Modulen.
Der PostgreSQL-Integrationstest verwendet eine ausdrücklich gesetzte
`ASSESSOR_TEST_DATABASE_URL`. Im verifizierten Abschlusslauf wurde eine
isolierte PostgreSQL-16-Instanz verwendet. Zusätzlich wurden ein Custom-Format-
Backup mit `pg_dump`, ein Restore in eine getrennte Datenbank und die enthaltene
Migrations- und Profildatenstruktur geprüft.
Die verbindlichen Import- und Workergrenzen sowie die geprüften Fehlerfälle sind in [docs/IMPORT_SECURITY_LIMITS.md](docs/IMPORT_SECURITY_LIMITS.md) dokumentiert.