Zum Inhalt springen
Vom Bauen zum Absichern: eine Woche ohne neue Funktionen

Vom Bauen zum Absichern: eine Woche ohne neue Funktionen

· Bert Altena

Eine Woche ohne neue Funktionen: ein Modul, das jede Datei mit drei Prüfungen verfolgt, vier Sicherheitsrunden und alle Geheimnisse aus dem Webverzeichnis.

In jedem Projekt kommt der Moment, an dem Weiterbauen nicht mehr das Klügste ist. Bei der Buchungsplattform, an der ich diesen Sommer arbeite, kam dieser Moment Ende Juli. Sechs Module standen, das System lief, und ich merkte, dass ich vor jeder Änderung immer länger suchte, was sonst noch daran hing.

Also habe ich eine Woche lang nichts Neues gebaut. Stattdessen: ein Modul, das den Zustand des Codes selbst verfolgt, vier Sicherheitsrunden und alles, was geheim bleiben muss, aus dem Webverzeichnis heraus. Das kam dabei heraus.

Drei Prüfungen pro Datei

Das größte Stück ist ein Modul, das ich Integritätsverwaltung nenne. Es erfasst das gesamte Projekt wie ein Dateiexplorer: Pfad, Größe, Änderungsdatum, Rechte, ein Hash des Inhalts und ob die Datei in der Versionsverwaltung steht.

Pro Datei verfolgt es drei Prüfungen getrennt. Ist das toter Code? Steckt veralteter oder unnötig umständlicher Code darin? Und ist es sicher? Erst wenn alle drei abgezeichnet sind, wird die Datei grün. Ändert sich der Inhalt danach, stimmt der Hash nicht mehr, das Abzeichnen fällt weg und die drei Schritte müssen erneut durchlaufen werden.

Genau darum geht es. Eine Prüfung sagt nur etwas über die Fassung, die man damals gelesen hat. Einbruchserkennung arbeitet seit dreißig Jahren so: man genehmigt einen Zustand bewusst und bekommt Bescheid, sobald sich dieser Zustand ändert. Ich habe dieses Modell übernommen und die Qualitätsprüfungen dazugestellt, denn die veralten genauso schnell.

Der Scanner läuft mit neun Regelpaketen: Offenlegung, Rechte und Herkunft, Schlüssel, Hintertüren, Injektion und XSS, Zugriffskontrolle, veraltetes PHP, die Hausregeln des Projekts und toter Code. Löschen geht nur über eine Schaltfläche, die zuerst eine Kopie in einem Archiv außerhalb des Webverzeichnisses ablegt.

Die eigentliche Arbeit steckte in den Fehlalarmen

Der erste Lauf über den echten Code ergab 3.578 Meldungen, davon 48 mit hohem Risiko. Unbrauchbar. Bei solchen Zahlen schaut niemand mehr auf die Liste, und dann ist ein Scanner schlimmer als gar keiner.

Zwei Tage Nachjustieren brachten das auf 518 Meldungen herunter, ohne dass ein echter Befund verloren ging. Die eine verbliebene Meldung mit hohem Risiko war berechtigt und wurde sofort geschlossen. Eine Testdatei voller absichtlicher Fehler wird weiterhin vollständig gefunden.

Was dabei schiefging, ist lehrreich. Ein Muster, das nach `require` suchte, erfasste auch das Wort `required` und meldete damit fünfzehn harmlose Zeilen als Codeausführung aus der Ferne. Eine Regel für `${var}` schlug bei JavaScript in einem Template an, wo dieselbe Schreibweise etwas ganz anderes bedeutet. Und achtzehn Handler wurden für eine fehlende Absicherung gemeldet, die eine Ebene höher längst zentral geregelt war.

Die Lehre daraus: eine Regel mit einem Wortanfang und einem freien Ende ist gefährlich. Lassen Sie jede neue Regel erst über das ganze Projekt laufen und schauen Sie, was sie fängt, bevor Sie sie scharf schalten.

Vier Runden an der Vordertür

Neben dem Scanner bin ich das System viermal selbst durchgegangen, jedes Mal mit einer anderen Brille.

Die erste Runde ging um Verwaltungsaktionen ohne eigene Kontrolle. Die zweite um die öffentliche Vorderseite. Die dritte fand rohes SQL, das über ein Buchungsfeld hereinkommen konnte, und einen Rechnungs-Endpunkt, der ungeschützt offen stand. Die vierte fand zwei Stellen, an denen Beträge ohne Anmeldung abrufbar waren, dazu drei Dinge, die ich in Runde drei selbst kaputt gemacht hatte.

Dieser letzte Satz steht bewusst da. Bei solcher Arbeit baut man neue Fehler ein, und das einzige Gegenmittel ist erneutes Hinsehen. Die Anmeldung bekam eine Bremse, Schreibaktionen über GET eine Tokenprüfung. Über dreißig Verwaltungsaktionen bekamen eine Rollenkontrolle; bis dahin verließen sie sich nur auf "ist angemeldet".

Schlüssel raus

Die Plattform nutzte einen einzigen Schlüssel für zu viele Dinge gleichzeitig: Sitzungen, Links in E-Mails, Passwortwiederherstellung. Das ist bequem, bis zu dem Tag, an dem einer davon nach außen gelangt.

Dieser Schlüssel ist jetzt getrennt. Es gibt einen eigenen, langen Schlüssel zum Signieren von Links, mit HMAC und einem laufzeitsicheren Vergleich. Die Umstellung lief in drei Schritten, mit Rückfall, damit bestehende Kundenlinks weiter funktionierten, während nichts mehr auf den alten Schlüssel geschrieben wurde. Als der letzte Nutzer umgestellt war, konnte der alte weg.

In derselben Woche wurden alle alten Passwörter blockweise auf bcrypt umgestellt, für Kunden, Verwalter, Eigentümer und Bewerter. Und die historischen Kartendaten wurden aufgeräumt: Felder aus den Formularen entfernt, Entschlüsselungsabfragen gelöscht, alte Werte geleert. Daten, die man nicht aufbewahrt, können auch nicht nach außen gelangen.

Alles Geheime nach draußen

Die Konfiguration mit den Datenbankzugängen, die Protokolldateien, die Sicherungskopien, die Migrationen und die Dokumentation lagen alle im Webverzeichnis. Mit der richtigen URL und etwas Geduld sind solche Dateien oft schlicht abrufbar.

Sie liegen jetzt außerhalb des Webverzeichnisses, mit einem Rückfall, damit eine noch nicht umgezogene Installation weiterläuft. Die Auslieferung spiegelt die Migrationen an die neue Stelle und räumt die alte auf. Protokolle rotieren und haben eine Aufbewahrungsfrist. Das Verzeichnis `.git` ist geschlossen.

Das Schöne daran: die Integritätsverwaltung prüft jetzt selbst, ob dieser Umzug geklappt hat. Im Reiter Server steht, ob die Ordner wirklich außerhalb der Installation liegen und ob noch Protokolldateien im Webverzeichnis stehen. Ohne SSH, einfach auf dem Bildschirm.

Außerdem: fünf Sekunden gefunden

Nebenbei habe ich eine Messung eingebaut, die langsame Anfragen festhält, statt darüber zu rätseln. Das brachte sofort zwei Dinge.

Die Änderungsseite führte 6.489 Abfragen aus und führt jetzt 3 aus. Und irgendwo steckte eine gleichbleibende Verzögerung von fünf Sekunden, die niemand einordnen konnte. Es war der automatische Klassenlader, der immer wieder nach einer Datei suchte, die es nicht gab, und erst nach allen möglichen Pfaden aufgab.

So etwas findet man nicht durch besseres Nachdenken. Man findet es durch Messen.

Was ich daraus mitnehme

Eine Prüfung hat ein Haltbarkeitsdatum. Ohne Hash weiß man nicht, ob das Urteil noch für den aktuellen Inhalt gilt. Mit Hash weiß man es, und das ist der Unterschied zwischen einer Liste und einem System.

Ein lauter Scanner ist schlimmer als gar keiner. Man gewöhnt sich an rote Zeilen und übersieht dann die echten. Die Zeit für das Nachjustieren der Regeln ist die Investition, die das Werkzeug brauchbar macht.

Wartung ist Arbeit, kein Restposten. Eine Woche ohne neue Funktionen fühlt sich unproduktiv an, bis man zurückschaut und sieht, was zugegangen ist.

Weiterlesen

Läuft bei Ihnen ein System, von dem niemand mehr genau weiß, was darin steckt? Das ist normaler, als Sie denken, und es lässt sich lösen. Vereinbaren Sie ein unverbindliches Gespräch. Ich schaue zuerst, wo die Risiken liegen, bevor ich etwas empfehle.

Bert

Chat met ons