255 lines
16 KiB
Markdown
255 lines
16 KiB
Markdown
# Sicherheitsmodell
|
|
|
|
## Accepted Risk: dokumentierte externe Entscheidung
|
|
|
|
Ergaenzung 2026-09-10: Der lokale Accepted-Risk-Dialog speichert begruendete,
|
|
befristete Entscheidungen mit Verantwortlichen, separater Freigabedokumentation,
|
|
Massnahmen, Wiedervorlage und vollstaendiger Versionshistorie im bestehenden
|
|
Review-JSONB. Der eigene Same-Origin-Endpunkt prueft Projektzugehoerigkeit,
|
|
Pflichtangaben und erwartete Revision; die Repository-Transaktion haengt eine
|
|
serverdatierte Version an. Allgemeine Reviewaenderungen duerfen die vorhandene
|
|
Historie nicht ersetzen. Originalbefunde und technische Bewertungen bleiben erhalten.
|
|
|
|
Namen und Freigabereferenzen sind Angaben zu einer externen Entscheidung, keine
|
|
authentifizierten Signaturen. Das Formular verifiziert weder Personen noch
|
|
Nachweisinhalte oder Freigabeberechtigungen. Referenzen bleiben inerter Text;
|
|
es gibt keine neuen Uploads, Netzfreigaben oder externen Dienste. JSONB-Historie
|
|
und Revisionsschutz sind kein Schutz gegen Datenbankadministratoren und kein
|
|
unabhaengiges Aufbewahrungsarchiv. Bestehende Loeschregeln bleiben anwendbar.
|
|
SSO, Rollen, verbindliche Freigaberegeln und manipulationsnachweisbare Aufbewahrung
|
|
bleiben Voraussetzungen fuer den Firmenbetrieb in Phase 14. Details und die
|
|
geplante normalisierte Ablage stehen in [RISK_ACCEPTANCE.md](docs/RISK_ACCEPTANCE.md).
|
|
|
|
## Lokale Datenverarbeitung
|
|
|
|
HTML-Parser-Nachhaertung 2026-09-09: Attributnamen und -werte werden linear
|
|
gelesen, einschliesslich langer wertloser beziehungsweise fehlerhafter Attribute.
|
|
Dies vermeidet quadratisches Regex-Backtracking vor der eigentlichen Extraktion.
|
|
PingCastle-Verweisziele werden pro unveraendertem Markup indiziert; doppelte
|
|
Definitionen bleiben mehrdeutig, Zielreihenfolge und Quellpositionen erhalten.
|
|
Die Indizes leben nur im aktuellen Import. Workerzeit, Speichergrenzen und
|
|
Netzwerk-/Persistenzberechtigungen werden nicht erweitert. Der im Screenshot
|
|
gezeigte Report wurde nicht gelesen; die Reproduktion verwendet synthetische Daten.
|
|
|
|
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 freigegebenen externen Anwendungs-APIs sind die unten beschriebene,
|
|
manuell ausgelöste NVD-CVE-Anreicherung sowie das ausdruecklich konfigurierte
|
|
Work-LiteLLM fuer AI Overview. 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.
|
|
|
|
### PurpleKnight-Berichte
|
|
|
|
Workbook-Zusammenfassungen werden mit der generischen Tabellenextraktion
|
|
kombiniert, nicht anstelle der Indikatoren verarbeitet. HTML liest ausschließlich
|
|
inert eingebettete, begrenzte Datenobjekte aus lexikalisch erkannten
|
|
`window.reportJSON`- und `window["Category_n"]`-Zuweisungen. Zeichenketten,
|
|
Kommentare, HTML-Attribute und andere Raw-Text-Elemente sind keine Datenquellen.
|
|
Beschädigte Objekte, fehlende native IDs und konkurrierende Zuweisungen werden
|
|
abgewiesen. Wiederholte IDs und abweichende native Ergebnis-/Detailzähler
|
|
erzeugen Warnungen ohne stilles Verwerfen von Vorkommen. Null-Details ohne
|
|
Ergebnisse und ausdrücklich deklarierte leere Berichte bleiben zulässig.
|
|
Originalwerte, vollständige Zeitstempel, unbekannte Felder und native Quellpfade
|
|
bleiben erhalten; Summary und Berichtskontext sind von Findings getrennt.
|
|
Es entstehen keine neuen Ausführungs-, Netzwerk- oder Datenbankrechte.
|
|
|
|
### Strukturtreue bei PingCastle
|
|
|
|
XML-Attribute werden als separate Originalwerte mit exakten Quellpfaden geführt;
|
|
ausdrückliche Leere wird nicht als nicht erhoben interpretiert. Lexikalische
|
|
HTML-Auswertung respektiert zitierte Attribute und Raw-Text-Grenzen, sodass
|
|
Tooltip-Markup weder zu scheinbaren Tabellen noch zu Zelltext wird. Aktive
|
|
Attribute werden nur als vollständige Tag-Attribute entfernt. Fehlende native
|
|
Rule IDs, Dubletten und abweichende deklarierte Trefferzahlen besitzen explizite
|
|
Diagnosen; ein angekündigter, aber nicht lesbarer Befundbestand darf nicht als
|
|
erfolgreicher Nullbefund gelten. Regeln und Originalzähler bleiben getrennt.
|
|
Diese Änderung öffnet keine aktive HTML-, Netzwerk- oder Persistenzberechtigung.
|
|
Details und Grenzen: `docs/IMPORT_SECURITY_LIMITS.md`.
|
|
|
|
### Eingebettete Maester-Berichtsdaten
|
|
|
|
Maester-HTML kann neben JSON ein minifiziertes JavaScript-Objektliteral enthalten.
|
|
Der Quellenextractor liest daraus ausschließlich statische Daten: Objekte, Arrays,
|
|
Zeichenketten (auch mehrzeilig ohne Interpolation), endliche Zahlen, Boolean und
|
|
Null sowie die festen Boolean-Schreibweisen `!0`/`!1`. Er führt keinerlei Code aus.
|
|
Aufrufe, Variablenzugriffe, Getter, Spread, berechnete Schlüssel, doppelte Schlüssel
|
|
und Template-Interpolation werden abgewiesen. Die Grenzen und Regressionen sind in
|
|
`docs/IMPORT_SECURITY_LIMITS.md` beschrieben. Importierte Skripte bleiben inaktiv;
|
|
es gibt keine neue Netzwerk-, Shell- oder Tauri-Berechtigung.
|
|
|
|
### 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.
|
|
|
|
### Externes Work-LiteLLM fuer AI Overview
|
|
|
|
- AI Overview ist ohne `ASSESSOR_AI_MODE=litellm` deaktiviert. URL, Modellalias
|
|
und Bearer-Key kommen ausschliesslich aus der Backendumgebung und werden nie
|
|
an den Browser, Exporte, Persistenz oder Logs weitergegeben.
|
|
- Eine externe Anfrage entsteht nur nach ausdruecklichem Generate/Regenerate.
|
|
Uebertragen wird ausschliesslich der bestehende versionierte
|
|
`resultsToPrivacySafeExportJson`-Inhalt des vollstaendigen aktiven Timeslots;
|
|
Rohdateien, Reviews, Quelltabellen, Storage Keys und nicht freigegebene
|
|
Environmentfelder bleiben lokal.
|
|
- Der konfigurierte Ursprung muss HTTPS verwenden, darf keine Credentials,
|
|
Query, Fragmente oder Loopbackadresse enthalten und kann nicht ueber die API
|
|
beeinflusst werden. Redirects sind verboten; Timeout und Antwortgroesse sind
|
|
begrenzt.
|
|
- Assessmentwerte bleiben nicht vertrauenswürdige Daten. Modellantworten werden
|
|
als inertes JSON geparst und lokal gegen Schema, Laengen, Quell-IDs,
|
|
Environment-Properties und direkte E-Mail-/IP-Identifier geprueft. React
|
|
rendert ausschliesslich Text, kein HTML oder Markdown.
|
|
- Persistiert werden nur Laufmetadaten und ein erfolgreich validiertes
|
|
Endergebnis. Prompts mit Assessmentdaten, Chunk-Zwischenergebnisse und
|
|
Providerantworten werden nicht aufbewahrt. Fehlgeschlagene Calls werden nicht
|
|
automatisch kostenpflichtig wiederholt.
|
|
- Das Ergebnis ist beratend und kann weder Score, Finding, Review, Accepted Risk
|
|
noch Importdaten veraendern. Weitere Details stehen in
|
|
[docs/AI_OVERVIEW_SECURITY.md](docs/AI_OVERVIEW_SECURITY.md).
|
|
|
|
## 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 prueft die
|
|
freigegebenen Backendclients fuer NVD sowie das explizite HTTPS-Work-LiteLLM; 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.
|