8 Min. Lesezeit

Warum sind täuschend ähnliche Genehmigungsanfragen gefährlich?

Täuschend ähnliche Genehmigungsanfragen können unterschiedliche Aktionen autorisieren. Erfahre, wie du Genehmigungen entwirfst und testest, damit Menschen die genaue Anfrage erkennen, die sie annehmen.

Warum sind täuschend ähnliche Genehmigungsanfragen gefährlich?

Eine menschliche Genehmigung hat nur dann einen Sicherheitswert, wenn die Person erkennen kann, was sie mit dem Klick autorisiert. Wenn zwei Anfragen auf dem Bildschirm gleich aussehen, sich aber ihr Inhalt, ihre Header, ihre Laufidentität oder ihre Befehle unterscheiden, wird die Genehmigung zur Farce. Die Person hat die Aktion nicht geprüft. Sie hat ein vertrautes Label erkannt und weitergeklickt.

Dieser Fehler entsteht bei Werkzeugen für Agenten leicht, weil die sichtbare Zusammenfassung meist mit den uninteressantesten Feldern beginnt: einem Titel, einem Hostnamen, einer Methode und vielleicht einem kurzen Befehl. Diese Felder helfen bei der Orientierung, definieren aber keine Berechtigung. Ein POST an denselben Endpunkt kann einen harmlosen Entwurf anlegen oder eine Änderung in der Produktionsumgebung veröffentlichen. Ein SSH-Befehl kann eine Version ausgeben oder ein Verzeichnis löschen. Eine Anfrage mit einem anderen Mandanten-Header kann eine Grenze überschreiten, auch wenn jedes Wort in der URL gleich bleibt.

Ich habe erlebt, wie Genehmigungsabläufe durch gute Absichten unbrauchbar wurden. Jemand möchte weniger Unterbrechungen und fasst deshalb ähnliche Aufrufe zusammen. Jemand möchte eine übersichtliche Karte und klappt deshalb den Anfrageinhalt ein. Jemand möchte für die Analyse ein stabiles Label und verwendet es deshalb für jede Aktion einer ganzen Gruppe. Wenn ein Prüfer die zehnte vertraute Karte sieht, hat das System ihm bereits beigebracht, dass die Details keine Rolle spielen. Der Angreifer oder der fehlerhafte Agent braucht dann nur eine einzige verborgene Abweichung.

Identische Labels können unterschiedliche Berechtigungen verbergen

Ein Titel und ein Ziel sind Hinweise, aber nicht das Objekt, das eine Person autorisiert. Wenn man sie als Identität behandelt, entsteht eine Kollisionsklasse: Viele unterschiedliche Vorgänge werden zu einer einzigen erkennbaren Aufforderung zusammengefasst.

Stell dir einen Bereitstellungsdienst mit einem einzigen Endpunkt vor, POST /v1/releases. Ein Agent übermittelt zuerst einen Bereitstellungsentwurf und bittet später darum, ihn zu veröffentlichen. Wenn beide Karten «Release request» sagen und api.example.test anzeigen, muss der Prüfer ein Detailfenster öffnen und den Inhalt lesen, um sie zu unterscheiden. In der Praxis bringen wiederholte Karten den Menschen bei, dass das Fenster jedes Mal denselben Ballast enthält. Die Anfrage zum Veröffentlichen kommt nach dieser Gewöhnung.

Dasselbe Problem tritt bei alltäglicheren Aufgaben auf. Eine Quellcodeverwaltungs-API kann denselben Pfad verwenden, um den Titel eines Pull Requests zu ändern, eine Merge-Einstellung anzupassen oder Prüfer zu ersetzen. Eine Cloud-API kann denselben Ressourcenpfad für einen Probelauf und eine tatsächliche Änderung verwenden, die durch ein einziges Feld unterschieden werden. Ein Ticket-Endpunkt kann je nach Header in einen privaten Vorfall oder eine öffentliche Statusseite schreiben. Das Ziel zeigt, wo die Anfrage angekommen ist. Es zeigt nicht, was der entfernte Dienst tun wird.

Bei Befehlen beginnt die trügerische Ähnlichkeit oft mit einer freundlichen Anzeige. Diese Paare dürfen niemals dieselbe Genehmigungsidentität haben:

  • find build -type f -delete und find build -type f -print
  • git push origin HEAD aus einem persönlichen Klon und aus einem Release-Checkout
  • curl -X POST mit einem JSON-Inhalt, der einen Entwurf erstellt, und mit einem Inhalt, der eine Nachricht sendet
  • ssh deploy@host mit einem schreibgeschützten Konto und mit einem Konto, das Servicedateien ändern darf

Der Unterschied, den Menschen verwischen, ist der zwischen Ähnlichkeit und Gleichwertigkeit. Ähnlichkeit bedeutet, dass zwei Aktionen genug gemeinsam haben, um sie visuell zu gruppieren. Gleichwertigkeit bedeutet, dass eine Genehmigung die andere Aktion tatsächlich abdecken darf. Das eine ist eine Frage der Darstellung. Das andere verleiht Berechtigungen. Wenn man beides vermischt, erweitert eine kompakte Oberfläche stillschweigend die Zugriffsrechte.

Eine Aufforderung darf wiederholte Aktionen zur besseren Lesbarkeit gruppieren, aber diese Gruppierung darf niemals entscheiden, ob ein früherer Klick auch für die nächste Aktion gilt. Die Autorisierungsprüfung braucht ein strenger definiertes Objekt als das Label auf der Karte.

Eine Genehmigung muss an die ausgeführte Anfrage gebunden sein

Das genehmigte Objekt sollte eine kanonische Beschreibung der Aktion enthalten, die der Ausführer senden wird, sowie den Identitätskontext, unter dem er sie sendet. Wenn sich ein berechtigungsrelevantes Feld ändert, muss das System erneut fragen oder die Änderung unübersehbar machen und eine neue Entscheidung verlangen.

Für HTTP umfasst diese Beschreibung normalerweise Methode, Schema und Host, den normalisierten Pfad, Abfragewerte, die Bytes des Inhalts oder eine definierte kanonische Inhaltsform, ausgewählte Header, die Referenz auf die Zugangsdaten und den Agentenlauf. Gib geheime Werte dafür nicht in der Anzeige oder im Protokoll aus. Eine Referenz wie payments-production identifiziert die Berechtigung, ohne das Token preiszugeben. Der Ausführer kann die Genehmigung an den internen Tresordatensatz binden, den er tatsächlich verwenden wird.

Header verdienen mehr Aufmerksamkeit, als ihnen die meisten Oberflächen geben. Manche beeinflussen nur die Transportdarstellung. Andere wählen eine Organisation aus, aktivieren einen Administrationsmodus, legen einen Idempotenzbereich fest, wählen ein regionales Konto oder ändern die Interpretation des Inhalts durch den Empfänger. Führe eine ausdrückliche Liste der Felder, die ausgelassen werden dürfen, weil sie die entfernte Aktion nicht beeinflussen können. Alle anderen Felder sollten in der kanonischen Identität bleiben, bis jemand nachweisen kann, dass ihr Weglassen ungefährlich ist.

Bei einem Befehl solltest du die Beschreibung aus dem Ausführungsplan erstellen und nicht aus einer Shell-Zeichenfolge. Der Plan umfasst das ausführbare Programm, den Argumentvektor, das Arbeitsverzeichnis, gegebenenfalls den Zielhost, die Benutzeridentität, die Referenz auf die Zugangsdaten und verhaltensrelevante Umgebungsvariablen. Eine Shell-Zeichenfolge ist eine verlustbehaftete Anzeigeform. Anführungsregeln, Expansionen, geerbte Variablen und ein verändertes Arbeitsverzeichnis können aus derselben scheinbaren Zeile eine andere Aktion machen.

An dieser Stelle schlagen Teams oft eine großzügige Regel vor: «Dasselbe Ziel und dasselbe Verb reichen ungefähr aus.» Die Regel ist beliebt, weil sie die Zahl der Aufforderungen schnell senkt und Demos flüssiger wirken lässt. Sie ist falsch, weil HTTP-Verben breite Klassen und keine Folgen beschreiben. POST ist keine Berechtigungskategorie, und ssh ist es ebenfalls nicht.

Verwende einen Anfragefingerabdruck, um die Entscheidung zu binden, aber zeige den Fingerabdruck nicht als einzigen Beleg. Ein Digest eignet sich hervorragend für einen Gleichheitscheck innerhalb der Genehmigungslogik. Menschen brauchen die Felder, die zu diesem Ergebnis geführt haben. Gib ihnen beides: strukturierte, lesbare Unterschiede auf der Karte und eine exakte kanonische Identität hinter der Karte.

Wiederholung beweist nicht, dass ein Aufruf sicher ist

Ein Wiederholungsversuch kann alle Ausführungsfelder mit einem früheren Versuch teilen und trotzdem anders behandelt werden müssen als ein unabhängiges Duplikat. Das System muss zuerst einordnen, warum die Aktion wiederholt wird, und erst danach entscheiden, ob es eine Aufforderung unterdrücken darf.

Der sicherste Fall einer wiederholten Anfrage ist ein Transport-Wiederholungsversuch, bei dem der Ausführer weiß, dass die erste Anfrage den entfernten Dienst nie erreicht hat, oder bei dem der entfernte Dienst einen Mechanismus zur Idempotenz bereitstellt, der an genau diese Aktion gebunden ist. Trotzdem sollte die Genehmigungslogik den Wiederholungsversuch an die ursprünglich genehmigte Aktion binden und die Beziehung dokumentieren. Sie sollte nicht einfach feststellen, dass irgendwo in der jüngeren Historie zwei Hashes übereinstimmen.

Ein Duplikat nach einem unsicheren Netzwerkausfall ist etwas anderes. Der entfernte Dienst kann den ersten Aufruf angenommen haben, bevor die Verbindung abbrach. Eine Wiederholung könnte eine zweite E-Mail senden, ein zweites Ticket anlegen oder doppelt abrechnen. Der Prüfer braucht eine Formulierung, die sagt, dass das Ergebnis des ersten Versuchs unbekannt ist. Eine vertraut aussehende Karte mit dem bloßen Text «Anfrage wird wiederholt» verbirgt die nötige Entscheidung.

Eine spätere identische Aktion aus einem anderen Lauf ist wiederum etwas anderes. Sie kann von einem neuen Agentenprozess, neuem Code, einer kopierten Terminalsitzung oder einer anderen Person am selben Rechner stammen. Eine Autorisierung pro Lauf gibt es, weil Prozessidentität und Lebensdauer eine Rolle spielen. Wenn man eine alte Genehmigung über mehrere Läufe hinweg wiederverwendet, wird aus einer begrenzten Entscheidung eine dauerhafte Freigabe.

Verwende in deinem Modell getrennte Zustände:

  1. Der Benutzer hat eine exakt geplante Aktion genehmigt.
  2. Der Ausführer hat diese Aktion versucht und weiß, ob er sie gesendet hat.
  3. Die entfernte Seite meldete Erfolg, Fehler oder ein unbekanntes Ergebnis.
  4. Eine spätere Aktion behauptet, mit der ersten Aktion zusammenzuhängen.

Fasse diese Zustände nicht in einem grünen Abzeichen zusammen. Eine Genehmigung dokumentiert eine Absicht. Ein Transportergebnis dokumentiert den Nachweis der Zustellung. Eine Antwort der entfernten Seite dokumentiert ein Ergebnis. Sie beantworten unterschiedliche Fragen, und das Prüfprotokoll sollte alle drei Informationen bewahren.

Inhalte brauchen eine semantische Prüfung und eine Bindung auf Byteebene

Ein Anfrageinhalt kann die gesamte Folge eines API-Aufrufs tragen. Ihn hinter einem allgemeinen Label wie «Payload angehängt» zu verbergen, ist deshalb ein Designfehler. Zeige eine lesbare Form zur Prüfung und binde die Genehmigung anschließend an die exakte Darstellung, die der Ausführer sendet.

JSON macht das schwierig, weil sich Aussehen und Bedeutung unterscheiden können. Die Reihenfolge von Objektfeldern ändert oft nicht die Interpretation durch den Empfänger, während die Reihenfolge in einem Array die Bedeutung vollständig verändern kann. Leerraum spielt normalerweise keine Rolle, ein String mit Leerraum aber schon. Eine als 1 geschriebene Zahl kann von einem Dienst mit lockerer oder eigener Dekodierung anders behandelt werden als 1.0. Erfinde keinen universellen JSON-Normalisierer und gehe davon aus, dass er die Semantik bewahrt.

Ein praktikabler Ansatz hat zwei Ebenen. Bewahre erstens die ausgehenden Bytes des Inhalts und berechne darüber einen kryptografischen Digest für die Autorisierungsbindung. Analysiere zweitens bekannte Inhaltstypen in einem Anzeigebaum, der die Felder lesbar macht. Wenn der Parser den Inhalt nicht sicher interpretieren kann, zeige einen maskierten Ausschnitt, seine Länge und einen Digest. Bei folgenreichen Aufrufen muss die Person den Inhalt vor der Genehmigung erweitern.

Teste mit Paaren, die einen flüchtigen Prüfer täuschen könnten. Die beiden Fixture-Dateien unten teilen sich Titel, Methode und Ziel. Sie müssen unterschiedliche Fingerabdrücke erzeugen und in der Genehmigungsansicht einen sichtbaren Unterschied zeigen.

{
  "title": "Release request",
  "method": "POST",
  "url": "https://api.example.test/v1/releases",
  "headers": {"Content-Type": "application/json"},
  "body": {"version": "2.4.1", "state": "draft"}
}
{
  "title": "Release request",
  "method": "POST",
  "url": "https://api.example.test/v1/releases",
  "headers": {"Content-Type": "application/json"},
  "body": {"version": "2.4.1", "state": "published"}
}

Dein Test sollte mehr prüfen als fingerprintA != fingerprintB. Er sollte sicherstellen, dass die gerenderte Karte state als geändert ausweist, dass eine Genehmigung für das Entwurfs-Fixture beim veröffentlichten Fixture fehlschlägt und dass der Aktivitätseintrag den Inhaltsdigest sowie die Zusammenfassung auf Feldebene bewahrt. Die letzte Prüfung fängt eine häufige Scheinlösung ab: Entwickler reparieren die Autorisierungsprüfung, lassen Prüfer und Ermittler aber weiterhin auf ein unbrauchbares Protokoll starren.

Binär- und Formulardaten brauchen dieselbe Sorgfalt. Ein Multipart-Upload kann Dateiname und Inhaltstyp beibehalten, während das hochgeladene Dokument ausgetauscht wird. Ein kodiertes Formular kann in einem Feld role=user zu role=admin ändern, das eine kompakte Karte nie anzeigt. Wenn die entfernte Aktion wichtig ist, ist auch der Inhalt wichtig.

Header und Zugangsdaten erzeugen verborgene Änderungen am Geltungsbereich

Einen störenden Lauf widerrufen
Widerrufe einen unerwünschten Agentenlauf direkt im Sitzungsjournal.

Die zum Senden einer Anfrage verwendeten Zugangsdaten sind Teil der Aktion, auch wenn URL und Inhalt Byte für Byte unverändert bleiben. Eine Karte mit dem Text «Rechnung aktualisieren», die verschweigt, ob Sandbox- oder Produktionszugangsdaten verwendet werden, bittet den Prüfer um eine blinde Genehmigung.

Zeige niemals ein Bearer-Token, Passwort, einen privaten Schlüssel oder einen benutzerdefinierten geheimen Header an. Weise stattdessen jedem Geheimniseintrag ein stabiles, für Menschen verständliches Label zu und zeige das Label, die Kontoklasse und den Berechtigungshinweis, den der Betreiber bewusst konfiguriert hat. Ein Prüfer muss den Tokentext vielleicht nicht sehen, aber er muss erkennen, dass sich billing-read zu billing-admin geändert hat oder dass die Aktion jetzt unter einem anderen SSH-Konto läuft.

Benutzerdefinierte Header sorgen für die unangenehmsten Überraschungen, weil sie oft wie reine Infrastruktur aussehen. Ein Wert in X-Organization kann eine ansonsten vertraute Anfrage in einen anderen Mandanten umleiten. Ein Header X-Mode: live kann die Grenze zwischen einer Simulation und einem echten Vorgang überschreiten. Ein Idempotency-Key kann entscheiden, ob der Empfänger eine Anfrage als Wiederholung oder als neue Anweisung behandelt. Zeige diese Felder im gerenderten Vergleich, wenn sie den Geltungsbereich beeinflussen.

Die Maskierung muss Änderungen weiterhin erkennbar machen. Jeden sensiblen Wert durch *** zu ersetzen, ist nur dann vertretbar, wenn die Oberfläche weiterhin anzeigen kann, dass sich die Geheimnisreferenz geändert hat. Wenn zwei verschiedene Geheimnisse beide als *** erscheinen, hast du selbst eine Kollision zwischen ähnlich aussehenden Anfragen gebaut. Zeige ein nicht geheimes Label oder einen stabilen internen Alias, niemals das Geheimnis selbst.

Eine nützliche Fixture-Sammlung ändert jeweils nur eine Dimension: dieselbe Anfrage mit einer anderen Referenz auf die Zugangsdaten, dieselben Zugangsdaten mit einem anderen Organisations-Header, derselbe Header mit einem anderen Abfragewert und schließlich alle Änderungen zusammen. Fälle mit nur einer Änderung finden Auslassungen im Kanonisierer. Der kombinierte Fall entdeckt UI-Code, der Unterschiede nach dem ersten Fund abschneidet.

Sitzungen zeigen, wer erneut anfragt

Eine Genehmigung ist auch ein Urteil über den Aufrufer. Dieselbe Aktion aus einem neuen Agentenprozess übernimmt nicht automatisch das Vertrauen, das du dem vorherigen Prozess gegeben hast, nur weil beide dasselbe Arbeitsverzeichnis oder denselben Programmnamen verwenden.

Codesignatur-Autorität ist nützlich, weil ein Prozess jeden beliebigen freundlichen Namen behaupten kann. Sie macht trotzdem nicht jede Anfrage dieses Prozesses gleich. Ein vertrauenswürdiger Prozess kann eine veränderte Aufforderung ausführen, eine manipulierte Repository-Datei lesen oder einer Anweisung folgen, die sein Betreiber nicht beabsichtigt hat. Die Prozessidentität beantwortet die Frage «Wer hat diesen Lauf gestartet?». Die Anfragebindung beantwortet die Frage «Was wird dieser Lauf tun?». Du brauchst beides.

Zeichne beim Start des Prozesses eine Sitzungskennung auf und hänge sie an jede vorgeschlagene und ausgeführte Aktion. Wenn ein Prozess endet, sollte auch seine vorübergehende Autorisierung enden. Wenn ein neuer Prozess erscheint, zeige eine neue Genehmigung, selbst wenn Titel und Ziel zu einer kürzlich ausgeführten Aktion passen. Entscheide nicht anhand desselben Pfads zum ausführbaren Programm, dass zwei Prozesse identisch sind. Aktualisierer, kopierte Binärdateien, Wrapper und lokale Entwicklungs-Builds machen diese Abkürzung unzuverlässig.

Sei bei langlebigen Werkzeugen vorsichtig. Ein Prozess, der tagelang läuft, verdient keine unbegrenzte pauschale Genehmigung, nur weil er noch nicht beendet wurde. Für sensible Zugangsdaten oder Aktionen mit unumkehrbaren Folgen solltest du eine Genehmigung für jeden Aufruf verlangen. Für wiederholte Arbeit mit geringem Risiko kannst du die Berechtigung an eine definierte Sitzung binden und die Sitzung im Journal sichtbar machen. Die Person, die das System bedient, sollte den Lauf mit unerwünschten Anfragen widerrufen können, ohne in einer umfassenderen Kontoeinstellung danach suchen zu müssen.

Sallyport verwendet standardmäßig eine sitzungsgebundene Autorisierung und kann für jede Verwendung eines ausgewählten Tresoreintrags eine Bestätigung verlangen. Diese feste Trennung ist leichter zu verstehen als eine Sammlung von Ausnahmen, die während eines Vorfalls niemand mehr rekonstruieren kann.

SSH-Befehle brauchen einen Ausführungsplan, keine hübsche Zeichenfolge

Eine Ausweitung der Richtlinienlogik vermeiden
Sallyport bietet drei feste Kontrollen: Tresorsperre, Sitzungsfreigabe und Bestätigung pro Schlüssel.

Shelltext eignet sich besonders gut dazu, sich als etwas anderes auszugeben. Der Prüfer sieht einen kompakten Befehl, während die Shell Aliase auflöst, Variablen expandiert, ein Verzeichnis übernimmt und sich mit Zugangsdaten verbindet, die in der Anzeige nie genannt werden.

Wenn dein Ausführer einen direkten Argumentvektor akzeptiert, behalte dieses Format bei. Zeige das ausführbare Programm und jedes Argument als eigenes Feld. Ergänze das aufgelöste Arbeitsverzeichnis, den Host, den entfernten Benutzer und das Label der Zugangsdaten. Wenn du eine Shell aufrufen musst, mache diese Tatsache ausdrücklich sichtbar und zeige das genaue Shellprogramm sowie die Script-Bytes. Eine Karte, die den Inhalt von sh -c hübsch formatiert, aber sh -c selbst verbirgt, lässt den wichtigsten Teil aus.

Diese Befehle sehen verwandt aus, autorisieren aber materiell unterschiedliches Verhalten:

ssh [email protected] 'systemctl status web'
ssh [email protected] 'systemctl restart web'

Im einfachen Beispiel ist der Unterschied beim Verb sichtbar. In echten Fehlerfällen wird er besser verborgen: Eine Variable wird zu einem anderen Host expandiert, ein entfernter Pfad stammt aus einem Umgebungswert oder eine Befehlssubstitution holt Anweisungen aus einer Datei, die der Agent zuvor verändert hat. Erfasse Werte möglichst nach der Expansion. Wenn die Expansion entfernt stattfindet oder nicht sicher aufgelöst werden kann, weise auf diese Einschränkung hin und erzwinge eine bewusstere Genehmigung.

Behandle Lesen und Schreiben nicht als Eigenschaften, die sich immer aus dem Befehlstext ableiten lassen. cat kann einen Gerätelesevorgang mit Nebenwirkungen auslösen. Ein harmlos wirkender Client kann einen entfernten Hook ausführen. Verwende nach Möglichkeit explizite Befehlsfamilien mit bekannten Bedeutungen und verlange bei mehrdeutigen Shell-Ausführungen eine menschliche Genehmigung. Wer vorgibt, jeden Befehl präzise klassifizieren zu können, erzeugt falsches Vertrauen.

Teste die Grenze mit Kollisionspaaren

Genehmigungstests sollten mit Paaren beginnen, die eine Person für dieselbe Aktion halten könnte. Unit-Tests, die nur beweisen, dass der positive Fall eine Anfrage genehmigen und senden kann, helfen bei dieser Fehlerklasse kaum.

Erstelle eine Tabelle der berechtigungsrelevanten Dimensionen und für jede Dimension ein Paar von Fixtures. Halte Titel und Ziel in den meisten Fällen gleich. So beweist du, dass die Logik diese bequemen Labels nicht versehentlich als Identität verwendet.

Geänderte DimensionZu testendes PaarErwartetes Ergebnis
InhaltEntwurf gegenüber VeröffentlichungNeue Genehmigung und sichtbarer Inhaltsunterschied
HeaderEin Organisationswert gegenüber einem anderenNeue Genehmigung und angezeigter Mandant
ZugangsdatenStaging-Datensatz gegenüber ProduktionsdatensatzNeue Genehmigung und angezeigtes Label der Zugangsdaten
SitzungDieselbe Anfrage aus einem neuen ProzessGenehmigung für einen neuen Lauf
BefehlskontextDieselben Argumente mit einem anderen ArbeitsverzeichnisNeue Genehmigung und angezeigtes Verzeichnis

Führe diese Fälle auf drei Ebenen aus. In der Kanonisierungsebene werden unterschiedliche Identitäten erwartet. In der Autorisierungsebene versuchst du, Fixture B mit einer für Fixture A ausgestellten Genehmigung einzureichen, und erwartest eine Ablehnung. Auf der Oberflächenebene erstellst du einen Snapshot oder eine strukturierte Barrierefreiheitsaufnahme und stellst sicher, dass das geänderte Feld ohne Öffnen einer zusätzlichen Ansicht erscheint. Ein Unterschied, der erst nach mehreren Klicks sichtbar wird, wird von den meisten Prüfern übersehen.

Füge anschließend Mutationstests hinzu. Entferne in einem Testzweig jedes Feld einzeln aus der kanonischen Identität und prüfe, dass ein Kollissionstest fehlschlägt. Das wirkt pingelig, bis jemand ein Anfrageobjekt umstrukturiert und dabei stillschweigend aufhört, einen Header, ein Arbeitsverzeichnis oder ein Label für Zugangsdaten an den Genehmigungsadapter weiterzugeben. Der Test sollte diese Auslassung unüberhörbar machen.

Sallyports Aktionspfad bewahrt Geheimnisse in seinem verschlüsselten Tresor auf und gibt Ergebnisse an den Agenten zurück, nicht das Geheimnismaterial. Diese Trennung erleichtert Tests, weil ein Fixture auf Zugangsdaten-Datensätze über ihr Label verweisen kann, während der Test bestätigt, dass der Agent niemals die tatsächlichen Zugangsdaten erhält.

Ein plausibler Fehler beginnt mit einem harmlosen ersten Aufruf

Genehmigungen an die Sitzung binden
Sallyport beendet die vorübergehende Autorisierung, sobald der genehmigte Agentenprozess endet.

Stell dir einen Agenten vor, der Versionshinweise pflegt. Er erstellt über einen vertrauten Endpunkt einen Entwurf, und der Betreiber genehmigt die erste Karte, nachdem er den Inhalt geprüft hat. Anschließend nimmt der Agent mehrere kleine Änderungen an demselben Entwurf vor. Der Kartentitel bleibt «Release request», der Host bleibt gleich, und der Betreiber lernt, dass jede Genehmigung Routine ist.

Eine Repository-Anweisung weist den Agenten später an, «den Release fertigzustellen». Der Agent ändert nur state von draft zu published und fügt einen Header hinzu, der die Live-Organisation auswählt. Wenn die Oberfläche nur Titel, Host und Methode zeigt, sieht die letzte Karte genauso aus wie die vorherigen. Wenn der Genehmigungscache Aufrufe nach Titel und Ziel gruppiert, fragt das System möglicherweise nicht einmal erneut.

In dieser Geschichte braucht es weder ein kompromittiertes Modell noch einen spektakulären Exploit. Es genügen ein Agent, der einer schlechten Anweisung folgt, ein Prüfer, der sich an wiederholte Aufforderungen gewöhnt hat, und eine Oberfläche, die die beiden Felder verbirgt, welche die Wirkung verändert haben. Diese Bedingungen treten in gewöhnlicher Automatisierung auf.

Die Reparatur muss den gesamten Ablauf abdecken. Mache den geänderten Status und die Organisation sichtbar. Binde die Genehmigung an beide Werte und an den Datensatz der Zugangsdaten. Behandle die Live-Anfrage als neue Aktion, auch wenn der Rest übereinstimmt. Zeichne die vorgeschlagene Aktion, die Entscheidung und die Identität der gesendeten Anfrage so auf, dass ein Betreiber sie später prüfen kann. Nur die Karte oder nur den Cache zu reparieren, lässt einen anderen Weg für die Kollision offen.

Reibung gehört zu bedeutsamen Änderungen

Menschen genehmigen viele Routineaktionen, wenn das System sie ehrlich darstellt und Reibung nur dort einführt, wo sich die Berechtigung ändert. Dafür braucht es eine klare Regel: Bei einem exakt gleichen Wiederholungsversuch in einem bekannten, begrenzten Fall ist keine erneute Aufforderung nötig. Ein geänderter Inhalt, Header, Zugangsdaten-Datensatz, eine andere Sitzung, ein anderer Befehlskontext oder ein anderes Ziel verlangt eine neue Entscheidung.

Versuche nicht, eine unklare Karte durch mehr Warnfarben, längere Texte oder eine bedrohlicher wirkende Bestätigungsschaltfläche auszugleichen. Solche Techniken machen Routinearbeit langsamer und bringen Menschen dazu, visuelles Rauschen zu ignorieren. Platziere die entscheidungsrelevanten Werte in einem stabilen Layout, markiere Änderungen in klarer Sprache und bewahre genug Details auf, damit jemand die aktuelle Anfrage mit der zuletzt genehmigten vergleichen kann.

Wenn du eine Gruppe von Aktionen findest, die tatsächlich dieselbe Genehmigung teilen darf, dokumentiere die Behauptung ihrer Gleichwertigkeit im Code und in den Tests. Ein idempotenter Wiederholungsversuch kann beispielsweise eine unveränderliche Operationskennung tragen, deren genau einmalige Ausführung der entfernte Dienst garantiert. Das ist eine eng begrenzte Behauptung mit Belegen. «Diese Anfragen sehen in der Oberfläche ähnlich aus» ist kein Beleg.

Beginne damit, zehn kürzlich genehmigte Anfragen mit demselben Titel und Ziel zu sammeln. Vergleiche ihre kanonischen Anfragefelder, die Labels der Zugangsdaten und die Sitzungs-IDs. Wenn du Unterschiede findest, die der Prüfer auf der Hauptkarte nicht sehen konnte, hast du einen Autorisierungsfehler gefunden, auch wenn ihn noch niemand ausgenutzt hat.

FAQ

Wodurch sehen zwei Genehmigungsanfragen ähnlich aus?

Die offensichtlichen Bezeichnungen bleiben gleich, während sich die Berechtigung hinter dem Klick ändert. Das Ziel kann gleich bleiben, obwohl der Inhalt einen Zahlungsbetrag verändert, ein Header den Mandanten wechselt oder ein Befehl auf einen anderen Pfad zeigt.

Wie sollte ein Genehmigungssystem eine eindeutige Anfrage erkennen?

Verwende eine kanonische Darstellung der tatsächlich ausgeführten Anfrage und nicht den Titel der Karte. Dazu gehören Methode, normalisiertes Ziel, Inhaltsdigest, Identität der Zugangsdaten, relevante Header, Sitzungsidentität und Ausführungskanal.

Ist es sicher, einen zweiten identischen API-Aufruf automatisch zu genehmigen?

Nein. Eine wiederholte Anfrage kann ein legitimer Wiederholungsversuch, ein unbeabsichtigtes Duplikat oder eine Anfrage aus einem anderen Agentenlauf sein. Der Genehmigungsbildschirm muss zeigen, welcher Fall vorliegt, bevor jemand die Anfrage als Routine behandelt.

Welche HTTP-Header gehören in eine Genehmigungsanfrage?

Zeige nur Header, die Autorisierung, Routing, Mandantenzuordnung oder die Interpretation der Anfrage beeinflussen. Werte von Zugangsdaten werden ausgeblendet, aber das Label der Zugangsdaten und eine Änderung gegenüber der vorherigen Anfrage werden angezeigt.

Kann ein Anfrage-Hash die Anfragedetails in einer Genehmigungskarte ersetzen?

Ein Digest hilft beim Vergleich, beweist aber nicht, dass zwei Anfragen dieselbe Bedeutung haben. Halte die ursprünglichen strukturierten Felder zur Prüfung verfügbar, besonders wenn ein Inhalt Arrays, wiederholte Felder oder maskierten Text enthält.

Warum ist die Agentensitzung für Genehmigungen wichtig?

Teste die Sitzung als eigene Identitätsdimension. Derselbe Befehl kann durch einen neuen Prozess, einen neu genehmigten Lauf oder eine geerbte Shell eine andere Vertrauensentscheidung erfordern, auch wenn sein Text unverändert bleibt.

Wie teste ich eine Genehmigungsoberfläche für KI-Agenten?

Behandle Genehmigungen als Teil der Autorisierungsgrenze und teste sie mit gegensätzlichen Fixture-Paaren. Eine visuelle Prüfung ist nötig, aber du brauchst zusätzlich Zusicherungen, dass das Backend eine Genehmigung bei geänderter Berechtigung nicht wiederverwendet.

Was muss ein Mensch sehen, bevor er einen SSH-Befehl genehmigt?

Bei Shell-Aktionen gehören das ausführbare Programm, die Argumente, das Arbeitsverzeichnis, verhaltensrelevante Umgebungswerte, der Zielhost und die zur Authentifizierung verwendete Identität in die Anzeige. Eine schön formatierte Befehlszeile hilft erst dann, wenn diese Felder unterscheidbar bleiben.

Warum sind Genehmigungsanfragen gefährlich, wenn sie zu oft erscheinen?

Das führt zu Genehmigungsmüdigkeit und bringt Menschen dazu, einfach durchzuklicken. Ein besseres Design merkt sich eine Entscheidung nur bei derselben begrenzten Anfrage im selben Lauf und macht jede Abweichung sichtbar.

Welche Informationen sollte ein Prüfprotokoll für eine genehmigte Aktion behalten?

Ein manipulationssicheres Protokoll hilft dabei, Ereignisse im Nachhinein zu rekonstruieren. Es macht eine unklare Genehmigung jedoch nicht zu einer informierten Entscheidung. Zeichne die angezeigte Zusammenfassung und die kanonische Anfrageidentität auf, damit Ermittler beides vergleichen können.

Sallyport

Sallyport führt API-Aufrufe und SSH-Befehle für Ihren KI-Agenten aus. Die Schlüssel bleiben in einem lokalen Tresor auf Ihrem Mac; Sie geben jeden Lauf frei, und jede Aktion landet in einem versiegelten Journal.

© 2026 Sallyport · Open Source unter Apache-2.0 · Oleg Sotnikov