Serie: Programmieren lernen mit KI

Acht Sicherheitsfunde an einem Samstagmorgen

Acht Sicherheitsfunde, jeder Fix bis Samstagabend gelandet.

Acht Funde, ein Samstag Enterprise-Due-Diligence, jeder Fund geschlossen Eingabevalidierung Hartcodiertes Zugangsdatum Cipher-Suite-Richtlinie Use-after-free Thread-Safety Autorisierungs-Bypass Auth-Fehler-Logging Abhängigkeits-Rückstand 8 / 8 geschlossen + 6 neue dauerhafte Schutzmechanismen
Das Team, das das Audit willkommen heißt, ist das Team, dessen Codebasis besser wird.

Audits bringen Dinge ans Licht. Der ehrliche Weg ist, sie willkommen zu heißen, alles zu fixen und dauerhafte Schutzmechanismen auszuliefern — genau so verdient sich eine Runtime das Vertrauen von Unternehmen.

Das Audit landete Ende letzter Woche im Posteingang. Am Samstagmorgen hatte ich den Report auf dem einen Bildschirm offen und die Codebasis auf dem anderen. Acht kritische oder hohe Funde. Die Art von Posteingangs-Inhalt, die ein Wochenende definiert.

Das war Enterprise-Due-Diligence. Ein potenzieller Partner hatte sein Sicherheitsteam gebeten, einen Durchgang über die öffentliche API-Oberfläche zu machen, bevor dessen Anwälte weiter vorangehen würden. Die Funde waren konkret, gut erklärt und vollkommen fair. Es waren auch genau die Dinge, für die ein agentengesteuerter Workflow einen besonders anfällig macht, wenn man sich nicht bewusst dagegen wehrt.

Bis zum Ende des Samstags hatte jeder Fund einen landenden PR. Dieser Post handelt davon, was jeder einzelne war.

Was die Kategorien waren

Ich spreche über Kategorien statt über konkrete Exploit-Details, weil die Details jetzt gefixt sind und für einen Konkurrenten nicht interessant; die Kategorien sind das, wogegen sich andere Teams wappnen wollen werden.

Erstens: Eingabevalidierung an der öffentlichen REST-Oberfläche. Mehrere Endpoints vertrauten ihren Eingaben mehr, als sie sollten. Konkret: Längengrenzen bei String-Eingaben, Wertebereichsgrenzen bei numerischen Eingaben und strukturelle Validierung bei JSON-Payloads. Keine der fehlenden Validierungen war für sich genommen katastrophal. Die Kombination aus „keine Längengrenze hier plus kein Rate-Limit dort plus keine Auth-Prüfung an diesem Admin-Endpoint” ist die Art von Stapel, der katastrophal wird, sobald ein Angreifer die Oberfläche entdeckt hat.

Zweitens: ein hartcodiertes Zugangsdatum in einer Konfigurationsdatei. Anders als der HMAC-Fund vor ein paar Wochenenden. Das war eine Konfigurationsvorlage, die in der Beispielversion ein echtes Zugangsdatum eincommittet hatte. Die Absicht war gewesen, ein Beispiel-Zugangsdatum als Platzhalter auszuliefern; ausgeliefert wurde ein Beispiel-Zugangsdatum, das ein echter Wert aus der lokalen Umgebung eines Entwicklers war. Rotation, Entfernung aus dem Beispiel, Aufnahme in den Secrets-Scanning-CI-Durchgang.

Drittens: unsichere Cipher-Suite-Aushandlung. Ein Subsystem, das TLS mit einem externen Dienst aushandelt, akzeptierte Cipher Suites, die 2026 nicht mehr akzeptabel sein sollten. Konkret mehrere Pre-TLS-1.3-Suites mit bekannten Schwächen. Der Fix war, die Cipher-Suite-Liste auf eine reine TLS-1.3-Menge zu beschränken, mit einer dokumentierten Ausweichoption (einem expliziten Flag) fürs Testen gegen Legacy-Partnersysteme.

Viertens: ein Use-after-free an der C-API-Grenze. Die C-API einer der Runtime-DLLs hatte eine Funktion, die einen Zeiger auf internen Zustand zurückgab, den der Aufrufer weiter verwenden konnte, nachdem der interne Zustand durch einen nachfolgenden Aufruf auf demselben Handle freigegeben worden war. Klassische C-API-Falle. Der Fix war, von „vom Aufrufer gehaltener Zeiger”-Semantik zu „vom Aufrufer gehaltenes opakes Handle mit einem Get-by-Handle-Accessor” zu wechseln. Der Accessor gibt für die Dauer des Aufrufs eine frische Zeigerkopie zurück, und der zugrunde liegende Speicher wird nicht offengelegt.

Fünftens: ein Thread-Safety-Loch in der Lizenzierungsschicht. Zwei Threads konnten bei gleichzeitigen Verifizierungsaufrufen um dasselbe Lizenzierungszustand-Objekt konkurrieren. Unter Last konnte ein Thread einen teilweise aktualisierten Zustand sehen und falsche Schlüsse über die Lizenzgültigkeit ziehen. Der Fix war eine ordentliche Read-Write-Sperre um den Zustand, mit dem Verifizierungspfad optimiert für den Normalfall (Lizenz gültig, kein Zustandswechsel nötig).

Sechstens: ein Autorisierungs-Bypass an einem Admin-Endpoint. Einer der Admin-Endpoints hatte eine Authentifizierungsprüfung, aber keine Autorisierungsprüfung. Jeder authentifizierte Benutzer konnte ihn aufrufen, auch Benutzer ohne Admin-Rolle. Der Fix war, die Rollenprüfung hinzuzufügen, einen Unit-Test zu schreiben, der sowohl den Pfad „als Admin authentifiziert, erlaubt” als auch „authentifiziert, aber kein Admin, verweigert” prüft, und jeden anderen Admin-Endpoint auf dasselbe Muster zu auditieren. Drei weitere Endpoints hatten dasselbe Problem. Alle vier sind jetzt korrekt.

Siebtens: unzureichendes Logging bei Auth-Fehlschlägen. Wenn ein Benutzer sich zu authentifizieren versuchte und scheiterte, protokollierte die Runtime den Versuch, aber nicht genug Kontext, um ein Brute-Force- oder Credential-Stuffing-Muster zu untersuchen. Der Fix war, strukturiertes Logging bei jedem Auth-Fehlschlag hinzuzufügen, mit der IP-Adresse, dem ratenbegrenzten Zähler für diese IP und der versuchten Auth-Methode. Datenschutzfreundlich (kein Passwort-Inhalt wird geloggt), aber genug Kontext, um zu untersuchen, wenn eine Untersuchung nötig wird.

Achtens: Abhängigkeits-Update-Rückstand. Mehrere der Drittanbieter-Abhängigkeiten, die die Runtime einbindet, hatten bekannt-verwundbare Versionen im Manifest festgepinnt. Der Fix war, jede einzelne auf die neueste gepatchte Version zu aktualisieren, die Testsuite gegen die Updates laufen zu lassen und die kleine Anzahl an API-Form-Änderungen aufzulösen, die die Updates erforderten. Zwei der acht Updates erforderten Adapter-Änderungen in unserem Code; die anderen sechs waren Drop-in. Dependabot ist jetzt so konfiguriert, dass es das automatisch markiert.

Was ich aus einem Wochenende Sicherheitsarbeit gelernt habe

Drei Dinge. Nicht überraschend. Es wert, gesagt zu werden.

Sicherheitsfunde häufen sich. Acht Funde auf einmal ans Licht zu bringen ist viel. Das Muster, rückblickend, ist, dass sie alle eine gemeinsame Wurzel teilen: Die Runtime war in einem agentengesteuerten Workflow schnell gewachsen, wobei die Agenten Dinge isoliert-betrachtet korrekt implementiert haben. Übergreifende Belange wie Sicherheit sind genau die Art von Sache, die dem Review pro PR entgeht. Das Audit fängt ab, was das Review verpasst hat. Plant die Audits ein.

Manche Funde sind agentengetriebene Fehlermodi. Der Use-after-free in der C-API ist die Art von Sache, die ein Agent schreibt, wenn der Prompt sagt „lege diesen internen Zustand dem Aufrufer offen”, ohne Besitzsemantik anzugeben. Das Thread-Safety-Loch in der Lizenzierungsschicht ist ähnlich. Beide fangen dasselbe Muster ab: Agenten, die nicht nach Besitz und Nebenläufigkeit gefragt werden, produzieren Code, der beides ignoriert.

Manche Funde sind tempo-getriebene Fehlermodi. Der Abhängigkeits-Update-Rückstand ist kein Agentenproblem. Es ist ein „schnell ausliefern und keine Person haben, deren Job es ist, Abhängigkeiten frisch zu halten”-Problem. Der Fix ist Prozess (Dependabot) und Disziplin (auf Dependabots Alarme reagieren). Der Fix ist nicht „klüger sein.”

Die neuen Verteidigungen

Dauerhafte Schutzmechanismen landeten dieses Wochenende.

Ein Sicherheits-Scanner-Durchgang in CI. Statische Analyse für Eingabevalidierung, Secret-Scanning und Cipher-Suite-Richtlinie. Jeder PR läuft durch den Scan. PRs, die neue Funde einführen, werden zur Überprüfung markiert.

Ein Admin-Endpoint-Testmuster. Jeder Admin-Endpoint in der API hat jetzt einen gepaarten Test, der sowohl den Admin-erlaubt-Pfad als auch den Nicht-Admin-verweigert-Pfad prüft. Das Muster wird durch eine CI-Prüfung erzwungen, die nach @admin_required-Dekoratoren sucht und den Build fehlschlagen lässt, wenn der Dekorator ohne zugehörigen gepaarten Test vorhanden ist.

Eine Thread-Safety-Annotation für geteilten Zustand. Jedes geteilte Zustandsobjekt in der Runtime hat jetzt eine explizite Annotation über sein Nebenläufigkeitsmodell: unveränderlich, sperrgeschützt, sperrfrei mit explizitem Happens-Before oder Single-Threaded. Die Annotation ist Teil des Typs. Code, der den Zustand berührt, muss die Annotation erfüllen. Der Compiler erzwingt das für die sperrgeschützten und unveränderlichen Fälle; der Rest liegt beim Review.

Ein monatliches Sicherheitsaudit im Kalender. Nicht warten, bis ein Partner fragt. Das Audit ist ein stehender Punkt am zweiten Samstag jedes Monats. Der erste läuft im April.

Was Partner und Entwickler daraus mitnehmen sollten

Wenn du eine Engine für eine Partnerschaft evaluierst und gerade ein Audit anfordern willst: Dieses Team wird es willkommen heißen. Audits bringen Dinge ans Licht. Dinge werden gefixt. Die Codebasis wird besser. Die Partnerbeziehung wird besser. Die Disziplin, das Audit willkommen zu heißen, ist wichtiger als jeder einzelne Fund.

Wenn du als Enterprise-Sicherheitsprofi das hier liest: Ich bin offen für Vorschläge zum Audit-Rhythmus und zu den konkreten Dingen, die du dir wünschst, dass mehr Engine-Teams auditieren würden. Die Funde dieses Wochenendes waren die naheliegenden. Die nicht naheliegenden sind die nächsten, die ich finden will.

Wenn du einen agentengesteuerten Workflow betreibst und kürzlich kein Sicherheitsaudit durchgeführt hast: Tu es. Das Muster „Agent schreibt isoliert-korrekten Code, der übergreifende Belange verpasst” ist universell in dieser Workflow-Form. Das Audit ist, wie man die übergreifenden Belange abfängt. Ich habe keinen anderen Weg gefunden.

Check am Wochenende-Ende. Acht Funde geschlossen. Sechs neue Verteidigungen gelandet. Das nächste Audit steht im Kalender. Die Partnerbeziehung geht voran.

Zurück ans Bauen.

Eine spatiale Runtime, die Due Diligence besteht

RakuAI ist gebaut für Enterprise-Partner und Smart-Glasses-Hersteller — auditiert, gehärtet und ehrlich darüber. Sieh, wie wir für die Sicherheitslatte konstruieren, die dein Team überwinden muss.

← Alle Beiträge