Skip to content
Software-Checkdelta-sportsoftware-checkowasp

Zwei Systeme, mit KI gebaut. Was ein Blick von außen gefunden hat.

Delta-Sport hat Lagersystem und Service-App mit Claude gebaut, sauber dokumentiert. Was eine Durchsicht nach OWASP ASVS trotzdem fand, und warum das kein Argument gegen KI ist.

Marten Prieß

Marten Prieß

7 Min. Lesezeit
Astronauten inspizieren von außen den Rumpf einer Rakete vor dem Start

Im September hat mich Daniel Rübensam von Delta-Sport gebeten, zwei Systeme anzuschauen, die in den nächsten Wochen gemeinsam produktiv gehen. Zum Zeitpunkt der Durchsicht lief keines davon live, und es waren keine Kundendaten darin. Genau der richtige Moment für einen Blick von außen. Ein Lagersystem mit Anbindung an die Warenwirtschaft und den Paketdienst, und eine Service-App, die Reklamationen entgegennimmt, Kundenmails führt, per Sprachmodell klassifiziert und Erstattungen als Bankdatei erzeugt. Beides in wenigen Monaten gebaut, beides zum großen Teil mit Claude.

Ich will hier nicht erzählen, dass KI-gebaute Software schlecht ist. Das Gegenteil ist der Fall, und das ist der eigentliche Punkt.

Was ich vorgefunden habe

Erst einmal: mehr, als die meisten Häuser haben. Beide Systeme hatten eine nummerierte Liste von Entscheidungen mit Datum und Messwert. Die Service-App hatte eine eigene Security-Baseline und zwei Durchsichten hinter sich, eine extern, eine mit Claude. Es gab Known Issues, ein Runbook, einen Backlog. Niemand hat hier blind drauflosgebaut.

Und die Grundlagen stimmten. Anmeldung in beiden Systemen vollständig: Signatur, Aussteller, Zielgruppe, Algorithmus festgelegt, Abbruch ohne Konfiguration. Ich habe an einer laufenden Instanz des Lagersystems jeden geschützten Zugang ohne Berechtigungsnachweis aufgerufen, jeder wurde abgelehnt. Keine Zugangsdaten im Quellcode, durchgängig Schlüsseltresor und verwaltete Identitäten. Geldbeträge in ganzen Cent ohne Fließkomma. Die Übergabe an die Warenwirtschaft mit Zustandsautomat, Zeilensperre und eingefrorenem Beleg, lehrbuchhaft.

In keinem der beiden Systeme habe ich eine Schwachstelle gefunden, die einem Angreifer aus dem Internet Zugriff verschafft.

Was trotzdem offen war

Einige Dutzend Befunde, eine Handvoll davon kritisch. Nicht dort, wo man Sicherheitslücken vermutet, sondern in drei Bereichen, in beiden Systemen an denselben Stellen.

Gleichzeitige Zugriffe. Beide Anwendungen gehen davon aus, dass zwei Vorgänge nicht zur selben Zeit dieselben Daten anfassen. Im Lager betrifft das die Bestandszusage: Zwei gleichzeitige Reservierungen auf das letzte Stück wurden beide angenommen, und der nächtliche Abgleich hat die Spur davon beseitigt. Gemessen mit einem Integrationstest gegen eine echte Datenbank, nicht vermutet. In der Service-App betraf dasselbe Muster den Zahllauf, also die Stelle, an der Geld das Haus verlässt.

Bemerkenswert daran: Das Projekt beherrschte das Gegenmittel. An mehreren anderen Stellen waren die Sperren korrekt gesetzt. Es fehlte nicht das Wissen, sondern der Blick darauf, wo es am meisten zählt.

Die Produktionsumgebung. Sie unterschied sich von der Entwicklungsumgebung in Rechengröße, Ausfallsicherheit und Aufbewahrungsfristen. In keinem Sicherheitsaspekt. Netzregeln und Dienstkonten waren für die Entwicklung gedacht und für den Betrieb noch nicht enger gezogen, und die Laufzeitumgebung war eine Version, die keine Sicherheitspatches mehr bekommt. So etwas meldet kein Werkzeug; das sieht man nur, wenn man die Support-Zyklen im Kopf hat.

Die Erkennbarkeit von Störungen. In keinem der beiden Systeme gab es eine Alarmierung. Beide Zustandsmeldungen antworteten mit “ok”, auch bei gestoppter Datenbank; ich habe es ausprobiert. Genau diese Meldung war der Rauchtest der Auslieferung. Im Betrieb hieße das: Ein Ausfall fällt erst auf, wenn jemand anruft.

Dazu Kleineres, das sich summiert. Eine Schutzmaßnahme im Logging, sorgfältig gebaut, die auf Feldnamen zielte, die der Code so nicht verwendet; der Test dazu war grün, weil er genau diese Schreibweise prüfte. Ein Rate-Limiting, installiert und nirgends eingebunden. Kommandozeilen-Werkzeuge, die gegen die Datenbank aus der lokalen Konfiguration laufen, ohne zu zeigen, gegen welche. Solange es nur eine Entwicklungsumgebung gibt, ist das harmlos; mit dem Go-Live ist die Produktion einen Kopierfehler entfernt.

Warum KI das nicht sieht

Keiner dieser Befunde ist ein Fehler im Sinne von “der Code tut nicht, was er soll”. Der Code tat überall, was er sollte. Die Befunde liegen dort, wo die Frage lautet: Was passiert, wenn zwei Leute gleichzeitig klicken? Wenn die Datenbank weg ist? Wenn der Paketdienst nicht antwortet? Wenn jemand in zwei Jahren das Skript auf der falschen Umgebung startet?

Das sind keine Fragen an den Code, sondern an den Betrieb. Man stellt sie, weil man einmal nachts um drei einen Zahllauf zurückgedreht hat, oder weil man gesehen hat, wie ein Health-Endpunkt, der immer grün ist, drei Tage lang einen Ausfall versteckt. Ein Sprachmodell hat das nicht erlebt. Es baut, was beschrieben wird, und es baut es gut. Es baut nicht, wonach niemand gefragt hat.

Das ist auch der Grund, warum die zwei vorherigen Durchsichten andere Schwerpunkte hatten: Ein Pentest prüft Angriffe von außen, keine Nebenläufigkeit. Und eine Durchsicht mit Claude prüft den Code gegen das, was im Code steht.

Wie die Durchsicht gelaufen ist

Quellcode und Infrastrukturvorlagen beider Systeme, zwei Durchgänge: einmal mit der Projektdokumentation, einmal bewusst ohne, Kommentare als Behauptung behandelt. Für das Lagersystem eine lokal aufgesetzte Instanz, gegen die sich Dinge messen ließen. Als Rahmen die Kapitelsystematik des OWASP Application Security Verification Standard, damit nachvollziehbar bleibt, was geprüft wurde und was nicht.

Kein Pentest, kein Lasttest, kein Zertifikat. Ein Bericht mit Einordnung und Grenzen, jeder Befund mit Fundstelle, Einstufung und einem Auftrag, den das Team so an Claude geben konnte. Dazu, und das halte ich für den wichtigeren Teil: eine Seite “Was ausdrücklich so bleiben darf”. Das ist keine Höflichkeit. Das ist Bestand, den ein Team verteidigen kann, wenn der nächste Berater kommt und alles neu bauen will.

Anderthalb Stunden Termin, zwei Live-Nachweise (der rote Test, der Health-Endpunkt bei gestoppter Datenbank), die Fragen zum Dokument.

Was mit dem Code nichts zu tun hatte

Der Teil, der mir im Nachhinein am wichtigsten erscheint, stand in keinem Befund. Er kam im Termin auf und wurde danach ein eigenes Papier: die Themen, die man nicht im Repository sieht, sondern erst im Betrieb.

Der Mailweg zum Beispiel. Die Service-App verschickt viele Mails im Jahr und holt Antworten automatisch ab. Was passiert, wenn eine Adresse nicht existiert oder ein Postfach voll ist? Der Mailserver der Gegenseite schickt eine Unzustellbarkeitsmeldung, mit der Ticketnummer im Text. Die sieht für die Anwendung aus wie eine Kundenantwort und landet als solche am Vorgang. Der Sachbearbeiter sieht eine neue Nachricht und darunter seine eigene, scheinbar versendete. Der Fall sieht bearbeitet aus. Er ist es nicht, und niemand erfährt es. Dazu die Absenderdomain: ob sie so eingerichtet ist, dass große Mailanbieter die Mails überhaupt annehmen, und ob es eine Stelle gibt, an der jemand merkt, wenn ab morgen jede zehnte Mail zurückkommt.

Oder das Backup. Es gab eins. Die Frage ist nicht, ob es eins gibt, sondern ob schon einmal jemand zurückgespielt hat, und wie: Ein Vollrücksprung löscht alles, was seither erfasst wurde. Der übliche Weg ist ein zweites Datenbank-Exemplar, aus dem man gezielt holt, was fehlt. Das muss jemand dürfen und einmal geübt haben. Dazu Alarmierung, der Weg von Test nach Produktion und zurück, ein Lasttest vor der nächsten Spitze, und eine Spur am Vorgang, die auch festhält, was gescheitert ist, nicht nur, was sich geändert hat.

Nichts davon ist eine Sicherheitslücke. Nichts davon findet ein Scanner. Und nichts davon bekommt man aus Claude oder ChatGPT heraus, wenn man nicht weiß, dass man danach fragen muss. Das ist der eigentliche Unterschied zwischen einem Werkzeug und jemandem, der so etwas schon betrieben hat: Das Werkzeug beantwortet Fragen. Der Mensch stellt die, die fehlen.

Was ich daraus mitnehme

Erstens: Mit KI gebaute Software ist nicht das Problem. Die beiden Systeme waren in ihren Grundlagen besser als vieles, was ich aus zehn Jahren Agenturarbeit kenne. Die Frage ist nicht, ob man mit KI bauen soll. Die Frage ist, wer den Teil übernimmt, den die KI nicht kennt: Nebenläufigkeit, Betrieb, Umgebung, Alarmierung, der Weg in die Produktion und zurück.

Zweitens: Der Blick von außen muss nicht groß sein. Ein paar Tage für zwei Systeme, mit Bericht, Test und Termin, vor dem Go-Live. Das ist weniger als ein einziger Vorfall danach.

Drittens: Je besser ein Team dokumentiert, desto mehr findet eine Durchsicht. Das klingt paradox, ist aber logisch: Entscheidungen mit Datum und Messwert kann man prüfen. Bauchgefühl nicht.

Wenn bei euch jemand mit KI baut, und das wird in den nächsten Jahren in fast jedem Betrieb so sein: Lasst es irgendwann jemanden anschauen, der schon einmal etwas betrieben hat. Nicht, weil es schlecht ist. Sondern weil die Fragen, die fehlen, nur von dort kommen.

Zurück zum Blog
Share:

Weitere Beiträge