Kann HTTP-Request-Injection mit einem Zeilenumbruch beginnen?
HTTP-Request-Injection kann mit einem versteckten Zeilenumbruch beginnen. Erfahren Sie, wie Sie CRLF in Zielen und Headern ablehnen, bevor Anfragen mit Zugangsdaten gerendert werden.

Ein Credential Injector kann einen API-Schlüssel aus dem Kontext eines Agenten heraushalten und ihn dennoch in der falschen Anfrage senden. Das Problem entsteht, wenn das Gateway die Eingabe des Agenten als harmlosen Text behandelt und sie erst in HTTP-Syntax einfügt, nachdem die Zugangsdaten-Schicht ihre Aufgabe erledigt hat.
Ich habe Teams erlebt, die viel Mühe in Vault-Speicher, Freigabeaufforderungen und Auditprotokolle steckten, dann aber einen String-Formatter zwischen Agent und Netzwerk ließen. Dieser Formatter wird Teil der Sicherheitsgrenze. Akzeptiert er einen Wagenrücklauf oder Zeilenumbruch in einem Ziel, einem benutzerdefinierten Header-Namen oder einem vom Agenten gelieferten Header-Wert, können Daten die Struktur einer Anfrage erzeugen.
Die Lösung ist bewusst unspektakulär: Lehnen Sie Wagenrückläufe und Zeilenumbrüche ab, bevor die Anfrage gerendert wird, parsen Sie strukturierte Eingaben, statt sie mit Zeichenketten zusammenzusetzen, und testen Sie die Bytes, die den Prozess verlassen. Versuchen Sie nicht, das Problem durch Kürzen oder Ersetzen zu bereinigen. Eine abgelehnte Anfrage ist eindeutig. Eine reparierte Anfrage kann eine andere Anfrage sein.
Kann HTTP-Request-Injection mit einem Zeilenumbruch beginnen?
Ja. In HTTP/1.1 trennt ein Zeilenumbruch Teile der Nachricht. Fügt Code nicht vertrauenswürdigen Text in eine Anfragezeile oder Header-Zeile ein, ohne diese Grenze durchzusetzen, kann ein Angreifer CRLF, also Wagenrücklauf gefolgt von Zeilenumbruch, verwenden, um die aktuelle Zeile zu beenden und eine neue zu beginnen.
Ein vereinfachter anfälliger Renderer sieht oft harmlos aus:
GET {path} HTTP/1.1\r\n
Host: {host}\r\n
Authorization: Bearer {vault_token}\r\n
{custom_name}: {agent_value}\r\n
\r\n
Angenommen, der Agent liefert diesen Wert:
blue\r\nX-Forwarded-Host: internal.example
Die gerenderten Bytes enthalten jetzt einen zusätzlichen Header. Die Zugangsdaten sind nicht in den Prompt des Agenten gelangt. Der Agent hat die authentifizierte Anfrage trotzdem auf eine Weise beeinflusst, die der Entwickler nicht beabsichtigt hatte.
Dieselbe Fehlerklasse tritt bei einem Ziel-String auf, wenn ein Gateway die erste Zeile selbst erstellt, oder wenn eine Schicht eine URL parst und eine andere später Pfad, Host oder Proxy-Ziel per Textformatierung zusammensetzt. Das genaue Ergebnis hängt von der HTTP-Bibliothek und dem Verhalten zwischengeschalteter Systeme ab. Diese Unsicherheit ist kein Schutz. Wenn Komponenten die Grenzen einer Nachricht unterschiedlich auslegen, kann ein kleines Versäumnis bei der Validierung zu einem Sicherheitsvorfall werden.
RFC 9110 definiert HTTP-Feldzeilen als Syntax aus Feldname, Doppelpunkt und Feldwert. Zeilenumbrüche behandelt der Standard als Rahmung der Nachricht, nicht als normalen Inhalt eines Felds. Dieser Unterschied ist wichtiger als die allgemeine Warnung, „Benutzereingaben zu escapen“. Für diesen Zweck gibt es keine sinnvolle escapte Form eines Zeilenumbruchs innerhalb eines Header-Felds. Lehnen Sie ihn ab.
Ein Vault schützt Zugangsdaten, nicht die Form der Anfrage
Das Einfügen von Zugangsdaten und Request Injection lösen getrennte Probleme. Ersteres hält das Geheimnis vom Agenten fern. Letzteres stellt sicher, dass die Anfrage, die das Geheimnis erhält, die von einem Menschen freigegebene Form hat.
Betrachten Sie ein Tool, das einem Agenten erlaubt, eine Billing-API mit einem im Vault gehaltenen Bearer-Token aufzurufen und einen optionalen benutzerdefinierten Header akzeptiert. Ein Entwickler könnte den Header für risikoarm halten, weil das Token nie in den Tool-Argumenten erscheint. Dabei wird die Nähe übersehen. Eine eingeschleuste Zeile kann einen Weiterleitungs-Header hinzufügen, eine Content-Length ändern, einen Anwendungs-Header duplizieren oder ein nachgelagert verwendetes Audit-Label verfälschen. Die Zugangsdaten bleiben geheim, während die Aktion unsicher wird.
Ziele verdienen dasselbe Misstrauen. Ein Hostname, der wie Daten aussieht, kann zur Authority-Syntax werden. Ein Pfad kann zum Request-Target werden. Ein Proxy-Selektor kann ändern, wohin sich der Client verbindet. Kann der Agent einen dieser Werte beeinflussen, muss das Gateway entscheiden, welche Formen gültig sind, bevor es Zugangsdaten hinzufügt.
Deshalb ist eine Allowlist zugelassener Hostnamen nützlich, aber nicht ausreichend. Sie begrenzt, wohin eine geparste URL zeigen darf. Sie beweist nicht, dass jede Komponente dieselbe geparste URL erhalten hat, und verhindert keine Zeilenumbrüche in Benutzerinformationen, einer Header-Überschreibung oder einem String, der nach der Allowlist-Prüfung angehängt wird. Die Grenze muss Steuerzeichen ablehnen und strukturierte Werte bis zum HTTP-Client erhalten.
CR und LF ablehnen, bevor ein Anfrageobjekt existiert
Die sicherste Regel passt in einen Satz: Vom Agenten kontrollierte Zielfelder, benutzerdefinierte Header-Namen und benutzerdefinierte Header-Werte dürfen nach dem Dekodieren weder \r noch \n enthalten.
Wenden Sie diese Regel an, bevor Sie eine URL bauen, Header erstellen, eine Client-Option wählen oder einen Logeintrag schreiben, der später einen Anfragewiederholungsversuch speist. Prüfen Sie den ursprünglichen String auf wörtliche Steuerzeichen. Dekodieren Sie einmal gemäß dem Eingabevertrag und prüfen Sie anschließend auch den dekodierten String. Dekodieren Sie nicht wiederholt, bis sich nichts mehr ändert. Wiederholtes Dekodieren macht aus einem klaren Vertrag Ratespiel und kann überraschende Ergebnisse erzeugen.
Eine kompakte Validierungsfunktion hat die richtige Form, wenn sie Eingaben nicht repariert:
validateRequestText(field, value):
if value contains "\r" or "\n":
fail(field + " contains a line break")
return value
Prüfen Sie im echten Code den tatsächlichen String-Wert der Sprache, nicht seine gedruckte Darstellung. Eine JSON-Payload kann "\n" enthalten. Nach dem JSON-Parsing wird daraus ein einzelnes Zeilenumbruchzeichen. Wer auf die zwei sichtbaren Zeichen Backslash und n prüft, übersieht den gefährlichen Wert.
Rufen Sie nicht trim() auf und machen Sie weiter. In den meisten Implementierungen entfernt Trimmen nur die Ränder, sodass ein Zeilenumbruch in der Mitte erhalten bleibt. Zeilenumbrüche durch Leerzeichen zu ersetzen, ist auf andere Weise noch schlechter: Es verändert die angeforderte Aktion, ohne dass der Betreiber klar erkennen kann, dass der Agent verbotene Syntax angefordert hat. Behandeln Sie die Eingabe als ungültig und stoppen Sie vor Netzwerk-I/O.
Die Ablehnungsantwort sollte das Feld nennen, aber keine sensiblen Inhalte zurückspiegeln. custom header value contains a line break sagt dem Aufrufer genug. Den vollständigen Wert auszugeben, kann Zugangsdaten oder private Daten in ein Terminalprotokoll schreiben.
Header-Namen brauchen einen engeren Vertrag als Werte
Ein Header-Wert darf berechtigterweise Leerzeichen und viele sichtbare Zeichen enthalten. Ein Header-Name sollte das nicht. Wenn ein Agent beliebige Namen auswählen darf, entsteht mehr Mehrdeutigkeit, als die meisten Aktions-Gateways benötigen.
Verwenden Sie eine konservative Namensregel: nur ASCII-Buchstaben, Ziffern und Bindestriche, ergänzt um eine angemessene Längenbegrenzung. Lehnen Sie Doppelpunkte, Leerraum, Steuerzeichen und Nicht-ASCII-Bytes ab, sofern es keinen dokumentierten Grund gibt, eine bestimmte Erweiterung zu unterstützen. Ziel ist nicht, jeden nachsichtigen Parser im Internet nachzuahmen. Ziel ist eine eindeutig interpretierbare Anfrage.
Diese Eingabe muss fehlschlagen, obwohl ihr sichtbarer Wert gewöhnlich wirkt:
{
"name": "X-Trace\r\nAuthorization",
"value": "debug"
}
Das gilt auch für diese:
{
"name": "X-Trace: injected",
"value": "debug"
}
Ein Doppelpunkt gehört zum Renderer, nicht zum gelieferten Namen. Akzeptiert das Gateway ihn, kann ein Parser einen Namen sehen, während ein anderer eine vollständige Feldzeile sieht. Ein Header-Name mit führendem Leerraum lädt zu ähnlichen Unterschieden ein.
Für Header-Werte brauchen Sie über CRLF hinaus eigene Regeln. Entscheiden Sie, ob das Gateway wiederholte Header akzeptiert, ob es Kommas erlaubt und welche Header Agenten überschreiben dürfen. Fassen Sie doppelte Namen nicht durch Zusammenfügen von Text zusammen, außer die Semantik des Headers erlaubt es ausdrücklich. Set-Cookie, Content-Length, Host, Authorization und Weiterleitungs-Header brauchen besondere Behandlung oder eine harte Sperre. Ich bevorzuge Gateways, die Protokoll- und Zugangsdaten-Header vollständig reservieren und Agenten nur eine kleine Auswahl von Anwendungs-Headern anbieten.
Diese Empfehlung stößt manchmal auf Widerstand, weil beliebige benutzerdefinierte Header ein allgemeines HTTP-Tool flexibel wirken lassen. Flexibilität ist beliebt, weil keine neue Tool-Option hinzugefügt werden muss, wenn eine API noch einen Header verlangt. Für Agentenverkehr mit Zugangsdaten ist sie trotzdem nicht die richtige Voreinstellung. Eine benannte Option wie idempotency_key oder request_id hat ein klares Format und einen Verantwortlichen. Ein uneingeschränkter Header-Satz hat beides nicht.
Ziele einmal parsen und ihre Teile strukturiert halten
Ein Ziel ist kein String mehr, nachdem das Gateway es akzeptiert hat. Es ist ein strukturierter Wert mit Schema, Host, Port, Pfad, Query und manchmal Benutzerinformationen oder einem Fragment. Parsen Sie ihn einmal mit einem standardkonformen URL-Parser, lehnen Sie unzulässige Bestandteile ab und übergeben Sie den geparsten Wert dem HTTP-Client, ohne ihn zurück in einen Template-String zu verwandeln.
Die genaue Allowlist hängt von der Aktion ab. Ein Tool, das eine API eines einzelnen Anbieters aufruft, kann HTTPS, einen Hostnamen und Port 443 verlangen. Ein breiteres Tool kann mehrere vorkonfigurierte Origins zulassen. Lehnen Sie in beiden Fällen eingebettete Zugangsdaten, Fragmente, fehlerhafte Hostnamen und jeden dekodierten Wagenrücklauf oder Zeilenumbruch ab, bevor die Anfrage entsteht. Fragmente werden nicht übertragen, sorgen aber in Logs und Freigabemasken für unnötige Verwirrung.
Eine sinnvolle Anfrageschranke sieht so aus:
input destination
-> decode once
-> reject CR and LF
-> parse URL
-> require HTTPS
-> require allowed host and allowed port
-> reject user info and fragment
-> pass parsed URL to HTTP client
Die Reihenfolge ist bewusst gewählt. Eine Host-Allowlist auf einen Roh-String anzuwenden, kann durch Benutzerinformationen wie https://[email protected]/ getäuscht werden. Eine Zeilenumbruchprüfung erst dann anzuwenden, nachdem eine Bibliothek einen fehlerhaften Wert normalisiert hat, kann übersehen, was ein früherer Parser akzeptiert hat. Parsen Sie für die Bedeutung, lehnen Sie verbotene Steuerzeichen aber ab, bevor eine Komponente sie als Syntax rendern kann.
Bauen Sie keine HTTP-Anfrage, indem Sie scheme + "://" + host + path verketten. Dieses Muster verwandelt einen strukturierten Wert genau dann wieder in Text, wenn Sie die Garantien des Parsers am dringendsten brauchen. Benötigt eine Bibliothek getrennte Argumente für Host und Pfad, validieren Sie jedes Argument mit derselben Steuerzeichenregel und nutzen Sie die strukturierte API der Bibliothek.
Kodierungen schaffen Umgehungen, wenn Schichten sich nicht einig sind
Wörtliches CRLF ist der Test, an den sich alle erinnern. Kodiertes CRLF ist der Test, der den eigentlichen Fehler findet.
Ein Agent kann %0d%0a in einer URL-Komponente senden. Prüft das Gateway den Roh-String und URL-dekodiert ihn später, bevor es einen benutzerdefinierten Renderer nutzt, hat die Prüfung die falsche Darstellung geschützt. Der daraus entstehende Zeilenumbruch erscheint erst nach der Validierung. Doppelte Kodierung wie %250d%250a wird relevant, wenn verschiedene Schichten getrennt dekodieren.
Wählen Sie eine ausdrückliche Normalisierungsgrenze. Parsen Sie zum Beispiel JSON einmal, prozent-dekodieren Sie nur dort, wo es der URL-Standard verlangt, validieren Sie die Darstellung, die Ihr Renderer verarbeitet, und verbieten Sie späteres allgemeines Dekodieren. Halten Sie für jeden Übergang einen Test vor. Das ist weniger spektakulär als ein großer Sanitizer, gibt Prüfern aber etwas, das sie nachvollziehen können.
Eine Testtabelle sollte für jedes vom Agenten kontrollierte Feld mindestens diese Eingaben abdecken:
- ein wörtliches
\r, ein wörtliches\nund ihre direkt aufeinanderfolgende CRLF-Form %0d,%0aund%0d%0a, wenn Prozentkodierung akzeptiert wird%250d%250a, falls eine andere Komponente später dekodieren könnte- einen Header-Namen mit Doppelpunkt oder Leerraum
- ein Ziel mit Benutzerinformationen, einem unerwarteten Port oder einem nicht freigegebenen Host
Testen Sie nicht nur auf eine Fehlermeldung. Stellen Sie sicher, dass der Client-Transport bei abgelehnten Eingaben nie ausgeführt wird. Ein Validator, der einen Fehler meldet, nachdem er die Anfrage aufgebaut oder in die Warteschlange gestellt hat, erfüllt die Sicherheitseigenschaft, um die es geht, bereits nicht mehr.
Es gibt eine verwandte Falle in Konfigurationsformaten. Umgebungsvariablen, YAML, JSON und Shell-Argumente haben jeweils eigene Escape-Regeln. Eine Test-Fixture, die sichtbar \n enthält, kann aus zwei harmlosen Zeichen bestehen, während die JSON-Dekodierung in der Produktion daraus einen Zeilenumbruch macht. Bauen Sie Tests über denselben Parsing-Pfad, der echte Agentenaufrufe annimmt.
Der Fehler versteckt sich meist in Komfortcode
Der gefährliche Code kommt oft nach der ersten Sicherheitsprüfung hinzu. Jemand ergänzt benutzerdefinierte Header für eine neue API, macht einen Debug-Proxy konfigurierbar oder schreibt eine Wiederholungsfunktion, die eine Anfrage fürs Logging rekonstruiert. Jede Änderung ist für sich genommen nachvollziehbar. Zusammen können sie String-Rendering wieder einführen, nachdem das ursprüngliche Gateway sichere Client-APIs verwendet hatte.
Ich habe solche Fälle gefunden, indem ich eine Aktion vom Eingang bis zum Socket verfolgt habe, nicht nur durch die Suche nach dem Wort header. Suchen Sie nach String-Interpolation rund um Host:, Authorization:, Cookie:, Content-Length:, Request-Targets, Proxy-Befehle, Raw-HTTP-Testhelfer und Log-Replay-Werkzeuge. Suchen Sie auch nach Dekodierfunktionen. Ein sicherer Validator am Einstiegspunkt hilft wenig, wenn ein späterer Pfad eine andere Darstellung akzeptiert.
Ein typischer Fehler besteht aus vier Teilen. Das Gateway prüft einen Ziel-Host gegen eine Allowlist. Den Rest des Ziels speichert es als Text für einen Low-Level-Client. Ein Wiederholungshelfer prozent-dekodiert diesen Text, damit Logs leichter lesbar sind. Anschließend schreibt der Helfer eine rohe Anfragezeile für den Wiederholungsversuch, und aus %0d%0aX-Test:%20yes ist Nachrichtensyntax geworden.
Keine dieser Zeilen sagt „Request Injection erlauben“. Der Fehler ist die fehlende Invariante: Nicht vertrauenswürdiger Inhalt darf nie Zeilenumbruchzeichen enthalten, wenn Code eine HTTP-Nachricht rendert. Legen Sie diese Invariante in einem gemeinsamen Validator fest und behandeln Sie Raw-Rendering als Ausnahme, die Tests begründen müssen.
Wenn Sie eine HTTP-Bibliothek auf höherer Ebene nutzen, bleiben Sie durchgängig auf dieser Ebene. Fallen Sie nicht auf einen rohen Socket zurück, nur um einen ungewöhnlichen Endpoint zu unterstützen. Verlangt eine API tatsächlich ein ungewöhnliches Wire-Format, geben Sie dieser Integration eine eigene Implementierung und ein enges Eingabemodell. Schwächen Sie dafür nicht den allgemeinen Pfad.
Logs müssen abgelehnte Absichten zeigen, ohne Geheimnisse zu wiederholen
Wenn die Validierung eine Anfrage ablehnt, erfassen Sie genug Kontext für die Untersuchung: Zeit, Agentensitzung oder Prozessidentität, Aktionsname, Feldkategorie, Ablehnungsgrund sowie einen sicheren Digest oder die Länge des gelieferten Werts. Speichern Sie nicht standardmäßig den vollständigen Header-Wert. Header enthalten oft Tokens, personenbezogene Daten oder signiertes Material. Werden sie in Logs kopiert, entsteht ein weiteres Problem für die Verwaltung von Geheimnissen.
Trennen Sie das Audit-Ereignis eines versuchten Vorgangs vom Ereignis eines ausgeführten Vorgangs. Eine abgelehnte Anfrage sollte nicht wie ein fehlgeschlagener Netzaufruf aussehen. Sie hat das Netzwerk nie erreicht. Dieser Unterschied hilft bei der Incident Response und verhindert, dass Betreiber einem entfernten Dienst nachgehen, der die Anfrage nie gesehen hat.
Sallyport führt ein Sessions Journal für Agentenläufe und ein Activity Journal für Aufrufe, beide abgeleitet aus seinem verschlüsselten, hash-verketteten Auditprotokoll. Damit hat ein Gateway einen sinnvollen Ort, um eine verweigerte Aktion zu zeigen. Die Eingaberegel gehört dennoch vor das HTTP-Rendering.
Die Eigenschaft der Offline-Prüfung ist hier wichtig. sp audit verify kann die Kette über Chiffretext ohne Vault-Schlüssel prüfen und so belegen, dass aufgezeichnete Ereignisse nicht verändert wurden. Es kann nicht feststellen, ob ein Validator zu großzügig war. Das Ereignisschema und die Tests müssen die Kategorie des abgelehnten Felds sichtbar machen, ohne gefährliche Daten aufzubewahren.
Die serialisierte Anfrage testen, nicht nur den Validator
Unit-Tests für contains('\r') || contains('\n') sind nötig, aber nicht ausreichend. Sie beweisen, dass eine Funktion zwei Zeichen ablehnt. Sie beweisen nicht, dass der tatsächliche Transport keinen Zeilenumbruch erhalten kann, der durch Dekodierung, Standardwerte, Wiederholungsversuche oder einen benutzerdefinierten Adapter eingeführt wurde.
Nutzen Sie einen lokalen Testserver oder einen aufzeichnenden Transport, der das ausgehende Anfrageobjekt und, soweit Ihr Stack es zulässt, seine serialisierten Bytes erfasst. Führen Sie erlaubte Eingaben über denselben Tool-Einstiegspunkt, den Agenten nutzen. Prüfen Sie Methode, Authority, Pfad und den vollständigen Header-Satz. Führen Sie dann abgelehnte Fälle zu und stellen Sie sicher, dass der aufzeichnende Transport null Anfragen gesehen hat.
Eine kompakte Testmatrix fängt mehr Regressionen ab als eine lange Sammlung vager Sicherheitstests:
field input expected result
custom header value "ok\r\nX-Added: yes" reject before transport
custom header name "X-Mode: injected" reject before transport
destination path "/v1/a%0d%0aX-Added:%20yes" reject after decoding
allowed destination "https://api.example/v1/a" one request, expected host
Fügen Sie Property-Tests hinzu, wenn die Sprache sie praktikabel unterstützt. Erzeugen Sie Steuerzeichen rund um jede akzeptierte Zeichenklasse und verlangen Sie anschließend Ablehnung. Fuzzing hilft erst, wenn der Vertrag klar ist. Ein Fuzzer findet ungewöhnliche Parser-Fälle, kann aber nicht sagen, ob beliebige Header-Namen eine Produktentscheidung oder ein Versehen waren.
Wenn ein Test fehlschlägt, untersuchen Sie die endgültigen Bytes, bevor Sie den Validator ändern. Ich habe Teams erlebt, die immer mehr Ersetzungen hinzufügten, bis ein Fall bestand, nur um festzustellen, dass der Client Leerraum gefaltet oder zweimal dekodiert hatte. Die richtige Reparatur besteht meist darin, den Formatter oder Decoder zu entfernen, der rohe Syntax ermöglicht hat.
Menschliche Freigabe entschuldigt keine fehlerhaften Aktionen
Eine Freigabe pro Sitzung beantwortet, ob ein bestimmter Agentenprozess handeln darf. Eine Freigabe pro Aufruf beantwortet, ob diese Nutzung einer geschützten Zugangsdaten eine menschliche Entscheidung verdient. Keine von beiden macht eine mehrdeutige Anfrage sicher. Niemand kann versteckte Steuerzeichen in einem langen Ziel oder Header-Wert zuverlässig prüfen, und Freigabemüdigkeit macht aus einer subtilen Aufforderung einen automatischen Stempel.
Halten Sie auch Freigabedaten strukturiert. Zeigen Sie einen normalisierten Host, Methode, Pfad, benannte Header-Kategorien und einen klaren Hinweis, wenn die Aktion Zugangsdaten hinzufügt. Lehnen Sie fehlerhafte Eingaben ab, bevor die Freigabekarte erscheint. Eine Person um die Freigabe einer ungültigen Anfrage zu bitten, verschiebt einen Parser-Fehler in die Benutzeroberfläche.
Das Vault-Gate, die Sitzungsautorisierung und die Schlüsselkonfiguration pro Aufruf von Sallyport bieten unterschiedliche Momente für menschliche Kontrolle. Die HTTP-Aktionsgrenze braucht weiterhin einen strikten Renderer, weil die Freigabeentscheidung eine wohlgeformte Aktion abdecken soll, keinen String, dessen Bedeutung sich nach dem Klick ändert.
Die erste praktische Änderung ist keine umfassende Neufassung. Finden Sie jeden Pfad, der vom Agenten kontrollierten Zieltext oder benutzerdefinierte Header akzeptiert, ergänzen Sie vor dem Rendering eine bedingungslose CRLF-Ablehnung und schreiben Sie einen Transporttest, der beweist, dass abgelehnte Eingaben nichts senden. Entfernen Sie dann den Komfortcode, der HTTP mit Strings rekonstruiert. Dort kehrt dieser Fehler immer wieder zurück.
FAQ
Sollte ich CRLF in HTTP-Header-Werten ablehnen?
Lehnen Sie beide Zeichen überall ab, wo sie in die Syntax einer Anfrage gelangen können: Ziel-Strings, Header-Namen, Header-Werte, Methodenüberschreibungen, Cookie-Fragmente und Proxy-Einstellungen. Behandeln Sie prozent-dekodierte Daten genauso. Die Prüfung muss erfolgen, bevor eine Zeichenkette eingefügt oder analysiert wird oder ein Bibliotheksaufruf die Eingabe normalisieren könnte.
Kann eine sichere HTTP-Bibliothek Request Smuggling verhindern?
Eine gewöhnliche HTTP-Client-Bibliothek hilft, ersetzt die Prüfung an der Grenze aber nicht. Ihr Gateway kann Agenteneingaben dekodieren, zusammenfügen oder formatieren, bevor sie die Bibliothek erreichen, und manche Eingaben beeinflussen zuerst einen anderen Parser. Wenn Zeilenumbrüche an der Grenze abgelehnt werden, ist der gewünschte Vertrag klar festgelegt.
Warum sind Wagenrückläufe in API-Anfragen gefährlich?
Nein. Zeilenumbrüche trennen die HTTP-Nachrichtensyntax. Wenn sie innerhalb eines Ziels oder Header-Felds erlaubt sind, können Daten zu einem weiteren Feld oder einem weiteren Anfragebestandteil werden. Der anfällige Code kann trotzdem eine syntaktisch gültige Anfrage senden, weshalb dieser Fehler bei normalen Tests verborgen bleiben kann.
Umgeht prozentkodiertes CRLF die Validierung?
Der Parser sollte einmal dekodieren und dann den dekodierten Wert prüfen. Akzeptiert er einen prozentkodierten Zeilenumbruch und dekodiert eine spätere Schicht ihn, kam die Prüfung zu früh. Halten Sie dekodierte und gerenderte Anfragewerte getrennt, damit späterer Code sie nicht erneut dekodiert.
Wie sollte ich benutzerdefinierte Header-Namen validieren?
Für Header-Namen sollte eine kleine Allowlist gelten, etwa Buchstaben, Ziffern und Bindestriche. Lehnen Sie alles andere ab. Das verhindert Zeilenumbrüche, eingeschobene Doppelpunkte, Tricks mit Leerraum und Namen, die verschiedene Komponenten unterschiedlich auslegen. Akzeptieren Sie keine beliebigen Header-Namen vom Agenten, nur weil der Wert geprüft wird.
Reicht URL-Parsing aus, um ein Agentenziel abzusichern?
Nein. Ein URL-Parser kann zeigen, wo die Grenzen von Host und Pfad liegen, aber nicht entscheiden, ob ein Ziel zulässig ist. Parsen Sie zuerst und wenden Sie dann eigene Regeln für Schema, Host, Port, Benutzerinformationen, Fragmente und dekodierte Steuerzeichen an.
Was sollte ein Aktions-Gateway tun, wenn es einen Zeilenumbruch sieht?
Lehnen Sie die Eingabe ab, bevor irgendein Anfrageobjekt entsteht. Kürzen Sie sie nicht, ersetzen Sie den Zeilenumbruch nicht durch ein Leerzeichen und entfernen Sie ihn nicht stillschweigend. Solche Reparaturen verschleiern die ursprüngliche Aktion in Protokollen und können die Bedeutung signierter oder authentifizierter Eingaben verändern. Geben Sie einen Fehler zurück, der das Feld nennt, ohne ein Geheimnis auszugeben.
Soll die Validierung vor oder nach der URL-Dekodierung stattfinden?
Prüfen Sie die Rohdaten, dann die einmal dekodierte Darstellung und in Tests schließlich die endgültig serialisierten Bytes. Die erste Prüfung fängt offensichtliche ungültige Eingaben ab, die dekodierte Prüfung erkennt Umgehungen durch Kodierung, und der Serialisierungstest deckt unsicheres Formatieren auf. Eine einzelne Prüfung lässt Raum dafür, dass eine spätere Umwandlung den Wert verändert.
Kann das Einfügen von Zugangsdaten zu Request Injection führen?
Auch wenn Zugangsdaten von vertrauenswürdigem Code hinzugefügt werden, kann die umgebende Anfrage weiterhin vom Agenten beeinflusst werden. Ein bösartiger Header-Wert kann einen zweiten Header neben den eingefügten Zugangsdaten platzieren, während ein bösartiges Ziel die Anfrage mit Zugangsdaten umleiten kann. Das Geheimnis zu schützen und die Form der Anfrage zu schützen, sind zwei getrennte Aufgaben.
Welche Testfälle erkennen HTTP-Header-Injection?
Testen Sie jede akzeptierte Eingabeposition mit einem wörtlichen Wagenrücklauf, einem wörtlichen Zeilenumbruch, CRLF, prozentkodierten Varianten, doppelt kodierten Varianten, führendem Leerraum und einem Doppelpunkt in einem Header-Namen. Stellen Sie sicher, dass das Gateway jeden Fall vor Netzwerk-I/O ablehnt. Prüfen Sie anschließend bei erlaubten Fällen eine aufgezeichnete Anfrage und verifizieren Sie, dass sie genau die vorgesehenen Felder enthält.