
Erkennt das CVE-2026-42945-Rewrite-Muster in nginx-Konfigurationen: rewrite mit ? in der Ersetzung plus einem unbenannten Capture, der in derselben Location konsumiert wird.
Findet Konfigurationen, die anfällig für CVE-2026-42945 sind, den Heap-Pufferüberlauf in nginx' ngx_http_rewrite_module.
Es reicht nicht aus, eine betroffene nginx-Version (0.6.27 bis 1.30.0) auszuführen, um ausnutzbar zu sein. Die Konfiguration muss ein bestimmtes Direktivenpaar enthalten, und dieses Paar ist selten: Zwei unabhängige Scans realer Konfigurationen fanden 0 ausnutzbare von 1465 und eine von 35633. Dieses Skript verrät Ihnen, auf welcher Seite dieser Grenze Sie stehen.
Ein rewrite, dessen Ersetzung ein ? mit anschließenden Argumenten enthält, gefolgt von einer unbenannten Erfassung ($1 bis $9), die in derselben location gelesen wird:
location / {
rewrite ^(.*) /new?c=1; # the ? here raises the internal is_args flag
set $myvar $1; # ...which was never cleared, and leaks into this
return 200 $myvar;
}
Ein Durchlauf dimensioniert den Puffer für die rohe Zeichenkette, der nächste kopiert eine maskierte Version hinein. Beide Hälften sehen für sich genommen korrekt aus.
Jede der folgenden Regeln wurde auf nginx 1.30.0 gemessen und nicht abgeleitet, denn die veröffentlichten Beschreibungen bekommen zwei davon falsch.
Zwei Konsequenzen sind hier erwähnenswert:
Ein nachgestelltes ? ist nicht gefährlich. /new/$1? ist die Art, wie Sie die vererbte Query-String verwerfen, und es kommt in einem großen Teil der Migrationskonfigurationen vor. Jedes ? zu markieren würde das halbe Internet anschreien.
„Benannte Erfassungen sind sicher“ ist falsch dargestellt. Entscheidend ist, wie die Erfassung gelesen wird, nicht wie sie deklariert wurde. Eine benannte Gruppe, die als $1 gelesen wird, stürzt genauso ab wie eine unbenannte.
Ebenfalls ignoriert, aus denselben gemessenen Gründen: ein ? innerhalb des Regex selbst (ein Quantor) sowie redirect / permanent / break, die die Verarbeitung beenden, bevor der Konsument läuft.
nginx -T | python3 check_rewrite.py
python3 check_rewrite.py /path/to/dump.txt
python3 check_rewrite.py --json /path/to/dump.txt
Python 3, nur Standardbibliothek.
Exit-Codes: 0 sauber, 1 ein Paar wurde gefunden, 2 die Konfiguration konnte nicht gelesen oder geparst werden. Der dritte ist der Punkt: Ein nicht geschlossenes Anführungszeichen oder unbalancierte geschweifte Klammern schneiden die Analyse ab, und ein Prüfer, der für eine Datei, die er nicht lesen konnte, „nichts gefunden“ antwortet, ist schlimmer als einer, der abstürzt. Wenn das passiert, sagt er es und gibt 2 zurück.
Füttern Sie es mit nginx -T, nicht mit einzelnen Dateien: Includes können überall liegen, und eine generierte Konfiguration gilt nur auf dem laufenden Server. Funde werden für die Datei und Zeile gemeldet, in der die Direktive tatsächlich steht, nicht für den Offset im Dump.
$ python3 check_rewrite.py samples/vuln-nginx-T.txt
[HIGH] находка #1
location: location / (/etc/nginx/nginx.conf:14)
rewrite: rewrite ^(.*) /new?c=1 (/etc/nginx/nginx.conf:15)
захват $N: set -> set $myvar $1 (/etc/nginx/nginx.conf:16)
почему: обработка продолжается в этом же location без редиректа
Итого находок: 1
Wird auch am Ende jedes Berichts ausgegeben, damit niemand das Werkzeug für eine Garantie hält:
location wird gemeldet;rewrite und set, die direkt in server statt in einer location stehen, werden nicht verfolgt;set $tmp $1; und anschließende Verwendung von $tmp) werden nicht verfolgt;try_files, error_page und benannte Locations werden nicht verfolgt;if, das nie greift, wird trotzdem gemeldet.Aktualisieren ist zuverlässiger als jede Konfigurationsprüfung. Nehmen Sie die aktuelle Stable- oder Mainline-Version von nginx.org.
python3 -m unittest test_check_rewrite -v
29 Tests. Die meisten davon sind Negativfälle, denn das Risiko bei einem solchen Werkzeug ist, Konfigurationen anzuschreien, die in Ordnung sind. Es wurde außerdem gegen eine Produktionskonfiguration mit 250 Zeilen über elf eingebundene Dateien ausgeführt, mit einem map-Regex und einem CSP-Header voller Semikolons in Anführungszeichen: null Funde, keine Parser-Beschwerden und genau ein Fund, sobald ein echtes Paar hinein injiziert wurde.
MIT
| Konfiguration in einer location | Absturz |
|---|
rewrite ^(.*) /new?c=1; + set $x $1; | ja |
rewrite ^/old/(.*)$ /new?x=1; + set $x $1; | ja |
rewrite ^/old/(.*)$ /new/$1?; + set $x $1; | nein |
rewrite ... /mid?c=1; dann rewrite ... /new; dann set $x $1; | nein |
rewrite ^(.*) /new?c=1 break; + set $x $1; | nein |
rewrite ^(?<tail>.*) /new?c=1; + set $x $1; | ja |
rewrite ^(?<tail>.*) /new?c=1; + set $x $tail; | nein |