Sapherbox logoSapherboxBlog
Alle Artikel

Ein Audit-Protokoll, das sich nicht unbemerkt ändern lässt

Ein Audit-Log taugt nur als Nachweis, wenn niemand es umschreiben kann. Sapherbox verkettet jeden Eintrag per HMAC mit dem vorigen, und ein Klick prüft die ganze Kette. Aufbau und Grenzen.

Auch verfügbar auf English

Jedes Compliance-Regelwerk verlangt ein Audit-Log, und die meisten Produkte haben eines. Es ist eine Tabelle, die festhält, wer wann was getan hat. Immer häufiger schieben Prüfer eine schwierigere Frage nach. Woher wissen Sie, dass in der Tabelle noch steht, was einmal geschrieben wurde? Ein Datenbankadministrator kann eine Zeile ändern. Ein Angreifer, der bis zur Datenbank vorgedrungen ist, kann die Einträge löschen, die seinen Weg dorthin zeigen. Ein Log, das sich unbemerkt bearbeiten lässt, zeigt, was jemand Sie glauben lassen will. Was tatsächlich geschehen ist, zeigt es nicht.

Das Audit-Log von Sapherbox ist so gebaut, dass keine Änderung unbemerkt bleibt. Dieser Artikel erklärt den Mechanismus, und der ist nicht kompliziert. Er erklärt auch die Teile drumherum, und die haben sich am Ende als wichtiger erwiesen als der Mechanismus selbst.

Zwei Schichten, weil eine nicht reicht

Die erste Schicht ist gewöhnliche Datenbankhygiene. Die Datenbankrolle, mit der sich die Anwendung verbindet, darf Audit-Zeilen einfügen und lesen. Ändern oder löschen darf sie sie nicht. Damit kann weder die Anwendung selbst noch jemand, der nur ihre Zugangsdaten besitzt, die Vergangenheit umschreiben.

Die zweite Schicht gibt es, weil die erste eine offensichtliche Lücke hat. Wer die Datenbank administriert, hat eine mächtigere Rolle, und wer diese Rolle stiehlt, ebenso. Für diese Personen ist eine gewöhnliche Tabelle frei bearbeitbar. Deshalb trägt jeder Audit-Eintrag einen Hash, und in jeden Hash fließt der Hash des vorigen Eintrags ein. Gesichert ist die Kette mit einem geheimen Schlüssel, den die Datenbank nie zu sehen bekommt.

Die Kette

Wenn der Server ein Audit-Ereignis schreibt, nimmt er die Felder, aus denen der Eintrag besteht. Das sind die Kennung, die handelnde Person, die Aktion, die betroffene Ressource, der maskierte Ressourcenname, die Client-Adresse, falls sie erfasst wurde, der Zeitstempel und eine kanonische Serialisierung der Detailfelder. Vor diese Felder setzt er den Hash des vorigen Eintrags. Getrennt werden die Felder durch ein Byte, das in ihnen nicht vorkommen kann. Über das Ganze berechnet der Server mit einem Signaturschlüssel einen HMAC-SHA-256. Das Ergebnis speichert er als Hash der Zeile, und es wird zum „vorigen Hash“ des nächsten Eintrags.

Daraus folgen zwei Eigenschaften. Ändert sich irgendein Feld eines Eintrags, ändert sich sein Hash, und der gespeicherte Hash passt nicht mehr. Weil außerdem der Hash jedes Eintrags in den nächsten einfließt, bricht ein geänderter Eintrag auch die Verbindung zum folgenden. Wird ein Eintrag gelöscht, reißt die Verbindung zwischen seinen Nachbarn. Die Kette verhindert also keine Manipulation. Sie macht sie sichtbar, und zwar beim ersten Eintrag, der sich nicht mehr verifizieren lässt.

Gegen einen Datenbankadministrator schützt das nur dank des Signaturschlüssels. Der Anwendungsprozess erhält ihn beim Start als Container-Secret, und er wird nie in die Datenbank geschrieben. Wer vollen Datenbankzugriff hat, aber den Schlüssel nicht, kann die Hashes nur neu berechnen, wenn er einen 256-Bit-Schlüssel errät. Wer Schlüssel und Datenbank zugleich besitzt, könnte die Vergangenheit umschreiben. Deshalb trennen wir beides. Wer die Datenbank betreibt, bekommt die Secrets der Anwendung nicht. Und die Datenbankrolle der Anwendung kann die Zeilen weder ändern noch löschen.

Beim Schreiben eines Eintrags sperrt der Server die Kopfzeile der Kette, eine einzelne Zeile mit dem aktuellen Stand der Kette. Er berechnet den neuen Hash, fügt den Eintrag ein und schreibt den neuen Stand in die Kopfzeile. All das geschieht in einer einzigen Transaktion. Treffen zwei Ereignisse gleichzeitig ein, schreibt der Server sie nacheinander. Es gibt genau eine Kette, ohne Verzweigungen.

Prüfen per Knopfdruck

Eine Kette, die niemand prüft, ist bloße Dekoration. Ein Administrator kann sie jederzeit auf der Einstellungsseite des Audit-Logs prüfen. Dieselbe Prüfung bietet auch die API, für alle, die sie per Skript ausführen möchten. Die Prüfung liest alle aufbewahrten Einträge der Reihe nach. Für jeden berechnet sie den Hash aus den gespeicherten Feldern mit dem Signaturschlüssel neu und vergleicht ihn. Entweder meldet sie dann, dass die Kette intakt ist, und nennt die Zahl der geprüften Einträge. Oder sie nennt genau den Eintrag, an dem die Kette zuerst bricht, und den Grund dafür. Das kann ein Hash sein, der nicht zu seinen Feldern passt, eine Verknüpfung, die nicht zum vorigen Eintrag passt, oder ein verschobener Anker.

Sapherbox meldet eine gebrochene Kette ausdrücklich als Sicherheitsvorfall, denn genau das ist sie. Entweder wurden die Daten verändert, oder jemand hat den Schlüssel gewechselt, ohne die Kette neu zu verankern. Beides verdient eine Untersuchung und kein Achselzucken.

Die Einstellungen des Audit-Logs: Aufbewahrung 365 Tage, die Option zur Protokollierung von IP-Adressen nicht aktiviert, darunter der Bereich „Tamper-evidence chain“ nach einem Klick auf „Verify chain“ mit der Meldung „Chain intact, 32 entries verified“

Spannend wird es bei der Aufbewahrung

Der beschriebene Mechanismus ist der einfache Teil. Schwierig wird es, weil ein Audit-Log nicht für immer nur wächst. Das Datenschutzrecht verlangt, Protokolle nicht länger als nötig aufzubewahren. Sapherbox löscht deshalb täglich alle Einträge, die älter sind als die Aufbewahrungsfrist des Tenants. Standardmäßig sind das 365 Tage.

Diese Bereinigung entfernt die ältesten Einträge. Danach beginnt die Kette also nicht mehr an ihrem ursprünglichen Anfang. Eine naive Prüfung würde jeden Tag einen Bruch an dieser Grenze melden. Deshalb verankert die Bereinigung die Kette neu. Sie speichert den „vorigen Hash“ des ältesten verbleibenden Eintrags als neuen Anfangswert der Kette, und die Prüfung beginnt dort.

Damit entsteht ein neuer Angriffsweg. Wenn sich der Anker verschieben lässt, könnte ein Angreifer mit Datenbankzugriff unbequeme frühe Einträge löschen und den Anker dahinter setzen. Die Kette würde trotzdem als intakt gelten. Das Design schließt diese Lücke, indem jede Bereinigung einen eigenen Audit-Eintrag schreibt. Dieser Eintrag ist wie jeder andere verkettet. In seinen Details steht, welchen Anfangswert die Bereinigung gesetzt und wie viele Einträge sie entfernt hat. Die Prüfung vergleicht den Anfangswert, der in der Kopfzeile der Kette gespeichert ist, mit dem Wert, den der jüngste Bereinigungseintrag bezeugt. Ein von Hand verschobener Anker ohne passenden Bereinigungseintrag fällt als abweichender Anfangswert auf. Wer auch den Bereinigungseintrag löscht, bricht die Kette an genau dieser Stelle. Die Bereinigung ist ein protokolliertes und authentifiziertes Ereignis, keine Lücke.

Was die Kette nicht leistet

Sie verbirgt das Log nicht. Das Audit-Log liegt bewusst im Klartext auf dem Server. Ein Administrator muss es lesen können, und die Prüfung muss es nachrechnen können. Die Ressourcennamen darin sind maskiert, wie in unserem Artikel darüber beschrieben, was der Server sehen kann. Die Ereignisse selbst sind lesbar.

Sie schützt nicht vor einem Angreifer, der sowohl die Datenbank als auch den Signaturschlüssel in die Hände bekommt. Dass beides getrennt bleibt, ist eine betriebliche Maßnahme und keine kryptografische. Das sagen wir offen.

Sie ersetzt keine externe Kopie. Die Kette beweist, dass das vorhandene Log nicht an Ort und Stelle verändert wurde. Einträge, die zusammen mit allem anderen gelöscht wurden, kann sie nicht zurückholen. Dafür gibt es den CSV-Export. Üblich ist, das Log in ein System zu übertragen, auf das die Administratoren des Tenants keinen Einfluss haben. Mit der Kette lässt sich die exportierte Kopie gegen das Original prüfen.

Und sie bewahrt keine Einträge über die eingestellte Frist hinaus auf. Das ist ja gerade der Sinn einer Aufbewahrungsfrist. Das Design macht das Löschen selbst zu einem Teil des Protokolls.

Für die Compliance-Akte

Wenn Sie eine Frage aus NIS2, DORA oder ISO 27001 zur Integrität von Protokollen beantworten müssen, lautet die Kurzfassung so. Die Einträge sind per HMAC-SHA-256 verkettet, mit einem Schlüssel, der außerhalb der Datenbank liegt. Die Anwendungsrolle kann keine Einträge ändern oder löschen. Die Bereinigung nach Ablauf der Aufbewahrungsfrist ist ein bezeugtes Ereignis. Und ein Administrator kann die gesamte aufbewahrte Kette jederzeit prüfen, in der Oberfläche oder per API. Die Langfassung ist dieser Artikel, und das Whitepaper ordnet die Maßnahme den einzelnen Anforderungen der Regelwerke zu.

Fragen?

Wenn Ihre Prüfer die Hash-Konstruktion, die Fehlerfälle der Prüfung oder das Verfahren zur Neuverankerung schriftlich haben möchten, schreiben Sie uns an hello@sapherbox.com.