Sicherheitsarchitektur

CWE-Matrix

Maßnahme CWE Beschreibung
Parametrisierte SQL-Queries CWE-89 Alle Werte über :P0:Pn Parameter gebunden
Identifier-Whitelist CWE-89 Tabellen-/Spaltennamen gegen [A-Za-z_][A-Za-z0-9_]* validiert
Expression-Blacklist CWE-89 Blockiert SELECT, INSERT, DROP, EXEC, xp_ in Ausdrücken
Enum-Range-Validierung CWE-20 Integer-Werte aus JSON gegen gültige Enum-Bereiche geprüft
Sanitisierte Fehlermeldungen CWE-209 ODBC-Details werden aus UI-Meldungen entfernt
Thread-Safety CWE-362 Owner-Form deaktiviert während Background-Operationen
Keine Credentials im Log CWE-532 Benutzername/Passwort nie in Log-Ausgaben
DPAPI-Verschlüsselung CWE-256 SQL-Passwörter user-scoped verschlüsselt
Heap-Scrubbing CWE-316 Credentials vor Freigabe mit Nullbytes überschrieben (CoW-sicher)
Release-Logging CWE-390 Keine leeren catch-Blocks — alle Fehler geloggt
TOCTOU-Validierung CWE-367 Mapping-Daten nach dem Laden nochmals validiert
Audit-Trail BSI/NIS2 SHA-1-Hashkette für manipulationssicheres Protokoll

DPAPI-Design

SQL-Authentifizierungspasswörter werden mit Windows DPAPI (Data Protection API) verschlüsselt.

Verschlüsselungsablauf

{ Encrypt: user-scoped DPAPI }
function EncryptPassword(const APassword: string): string;
begin
  Result := 'DPAPI:' + Base64Encode(
    CryptProtectData(UTF8Encode(APassword), CRYPTPROTECT_UI_FORBIDDEN)
  );
end;
  • Scope: User-scoped (CRYPTPROTECT_UI_FORBIDDEN)
  • Speicherformat: DPAPI: + Base64(Ciphertext)
  • Entschlüsselung: Nur auf demselben Windows-Benutzer und -Computer möglich
  • Fallback: Klartext-Passwörter (ohne DPAPI:-Prefix) werden akzeptiert und bei nächster Speicherung automatisch verschlüsselt

Re-Encryption

Wenn die Entschlüsselung fehlschlägt (anderer Benutzer/Computer):

  1. Passwort-Dialog wird angezeigt
  2. Nach korrekter Eingabe: Automatische Re-Encryption mit aktuellem DPAPI-Schlüssel
  3. Mapping-Datei wird mit neuem Ciphertext gespeichert

Heap-Scrubbing (CWE-316)

Credentials werden vor der Freigabe sicher aus dem Heap gelöscht:

{ CWE-316: Heap Inspection — CoW-safe zeroing }
procedure SecureZeroString(var S: string);
begin
  if Length(S) > 0 then
  begin
    UniqueString(S);                    { ensure own copy (no CoW sharing) }
    FillChar(S[1], Length(S) * SizeOf(Char), 0);
    S := '';
  end;
end;

Wichtig: UniqueString stellt sicher, dass der FillChar nur die eigene Kopie überschreibt — ohne UniqueString würde Copy-on-Write (CoW) andere Referenzen auf denselben String beschädigen.


SQL-Injection Prevention (CWE-89)

Dreistufige Verteidigung

  1. IsValidIdent — Whitelist-Prüfung aller Tabellen-/Spaltennamen aus Mapping-Dateien gegen [A-Za-z_][A-Za-z0-9_]*
  2. QuoteIdent — Klammert validierte Identifier in […] für SQL Server
  3. Expression-BlacklistfsExpression-Felder werden gegen gefährliche Schlüsselwörter geprüft (SELECT, INSERT, UPDATE, DELETE, DROP, EXEC, xp_)

Betroffene Felder

Alle folgenden Felder aus Mapping-Dateien werden vor SQL-Interpolation validiert:

  • Root: rootTable, primaryKeyColumn
  • Relation: targetTable, sourceColumn, targetColumn, primaryKeyColumn
  • FieldMapping: tableName, columnName, filterColumn, joinColumn

Audit-Trail Design

Format

TIMESTAMP|USER|OPERATION|DETAILS|PREV_HASH|ENTRY_HASH

Hash-Kette

  • ENTRY_HASH = SHA-1(TIMESTAMP + USER + OPERATION + DETAILS + PREV_HASH)
  • PREV_HASH des ersten Eintrags = 0000000000… (40 Nullen)
  • Jede Manipulation bricht die Kette → bei Prüfung erkennbar

Implementierung

{ All data-modifying operations MUST be logged via TOutlookSyncAudit.Log() }
class procedure TOutlookSyncAudit.Log(
  const AOperation, ADetails: string);

Protokollierte Operationen

  • SYNC_TO_OL / SYNC_TO_DB — Einzelzeilen-Sync
  • BULK_TO_OL / BULK_TO_DB — Massen-Sync (Start/Ende)
  • BIDIR_SYNC — Bidirektionaler Sync (Start/Ende)
  • OL_FOLDER_CREATE — Outlook-Ordner erstellt

→ Compliance-Details: Audit-Trail (BSI/NIS2)


Wolfgang van der Stille @ EMSR DATA d.o.o. — Outlook Sync

Zuletzt geändert: den 19.02.2026 um 21:17