Chrome behebt WebP-Sicherheitslücke mit Heap-Buffer-Overflow
(chromereleases.googleblog.com)- Updates für die Desktop-Kanäle Chrome Stable und Extended Stable wurden ausgerollt und enthalten unter anderem einen Fix für eine WebP-Heap-Buffer-Overflow-Schwachstelle
- Die neuen Builds sind 116.0.5845.187 für Mac und Linux sowie 116.0.5845.187/.188 für Windows und werden über mehrere Tage bis Wochen schrittweise verteilt
- Dieses Release enthält eine Sicherheitskorrektur, und CVE-2023-4863 ist als Critical eingestuft
- Apple SEAR und The Citizen Lab der Munk School der University of Toronto meldeten die Schwachstelle am 6. September 2023
- Google teilte mit, dass es reale Ausnutzungsfälle gibt; der Zugriff auf Bug-Details kann bis zur Verbreitung der korrigierten Version eingeschränkt bleiben
Update der Desktop-Chrome-Kanäle
- Die Kanäle Stable und Extended Stable wurden für Desktop auf neue Builds aktualisiert
- Die Stable-Channel-Versionen je Plattform sind wie folgt
- Mac: 116.0.5845.187
- Linux: 116.0.5845.187
- Windows: 116.0.5845.187/.188
- Auch der Extended Stable Channel wird mit eigenen Versionen ausgeliefert
- Windows: 116.0.5845.188
- Mac: 116.0.5845.187
- Das Update wird über mehrere Tage bis Wochen schrittweise ausgerollt
- Die vollständige Liste der Änderungen in diesem Build ist im log einsehbar
Sicherheitsfix: CVE-2023-4863
- Dieses Release enthält eine Sicherheitskorrektur
- Die wichtigste von externen Forschern beigesteuerte Korrektur betrifft die folgende Schwachstelle
- Critical CVE-2023-4863: Heap-Buffer-Overflow in WebP
- Bug-Nummer: 1479274
- Gemeldet von: Apple Security Engineering and Architecture (SEAR), The Citizen Lab der Munk School der University of Toronto
- Meldedatum: 6. September 2023
- Prämie: $NA
Reale Ausnutzung und eingeschränkte Offenlegung
- Google erklärte, dass ein CVE-2023-4863-Exploit in freier Wildbahn existiert
- Der Zugriff auf Bug-Details und Links kann eingeschränkt bleiben, bis die Mehrheit der Nutzer auf die korrigierte Version aktualisiert hat
- Die Einschränkung kann auch bestehen bleiben, wenn derselbe Bug in einer Third-Party-Bibliothek vorhanden ist, von der andere Projekte abhängen, und dort noch nicht behoben wurde
Erkennung von Sicherheitsbugs und Meldewege
- Viele Sicherheitsbugs werden mit den folgenden Tools erkannt
- Wie man den Release-Kanal wechselt, ist in der Anleitung zu den Chromium release channels beschrieben
- Neue Issues können auf crbug.com gemeldet werden; Hilfe gibt es im Chrome community help forum
1 Kommentare
Meinungen auf Hacker News
In Google Chrome werden WebP-Bilder im Renderer-Prozess decodiert. Selbst bei einem erfolgreichen Exploit ist daher nur Codeausführung im Renderer innerhalb der Sandbox möglich.
Der Renderer ist sehr komplex, weshalb jedes Jahr viele Exploits gefunden werden. Aber selbst wenn man Codeausführung im Renderer erreicht, kommt man kaum über die Rechte hinaus, die eine normale Webseite hat.
Insbesondere kann man keine Dateien im lokalen Dateisystem ansehen oder hinterlassen und auch keine Cookies anderer Domains lesen.
Es ist nicht sofort Priorität Nummer eins, aber sofern ein solcher Exploit nicht bereits in freier Wildbahn kursiert, sollte man so schnell wie möglich patchen, sobald es ohne größere Umstände passt.
Weil es nicht an eine bestimmte Site oder ein bestimmtes Frontend gebunden ist, ähnelt es eher einem verstärkten XSS.
Ah, ich habe im falschen Thread geantwortet; eigentlich wollte ich auf „jpeg is good enough“ in https://news.ycombinator.com/item?id=37479576 antworten.
Und kann die Website dann nicht plötzlich weiterhin Code ausführen, selbst wenn JavaScript deaktiviert ist?
Dadurch habe ich mehr Verständnis dafür, warum Browser-Entwickler bei der Einführung neuer Formate so langsam sind.
WebP bietet gegenüber JPEG keinen besonders großen Vorteil, hauptsächlich Transparenz, und selbst damit war der Erfolg begrenzt.
Nun hat es aber zu mehreren hoch priorisierten Sicherheitslücken geführt, und überall, wo gegen libwebp gelinkt wird, müssen im kommenden Monat Patches ausgeliefert werden.
Das heißt nicht, dass man nichts Neues machen sollte, aber ich denke, Entwickler unterschätzen die Kosten oft erheblich.
Das WebP-Ökosystem ist zwar deutlich weniger ausgereift, aber ich bin sicher, dass auch im Verarbeitungscode älterer Formate ziemlich viele Sicherheitsprobleme steckten.
Trotzdem ist die Argumentation stichhaltig. Noch vor ein paar Wochen war die Stimmung unter Internetnutzern, dass JPEG XL so schnell wie möglich eingeführt werden müsse und dies „fast nichts koste“, weil Browser-Entwickler dafür „nur den Referenz-Decoder-Code in die Codebasis aufnehmen“ müssten.
Andere Bildformate und Bibliotheken sind wahrscheinlich ebenfalls voller Bugs, aber da sie nicht in wichtiger Software verwendet werden, kümmert sich niemand darum.
Besonders für Leute, die solche Bugs finden und ausnutzen können, ist der Ertrag im Verhältnis zur Zeit schlecht.
Bugs werden nicht weniger, nur weil etwas lange nicht genutzt wird.
Wenn Bild-Encoder und -Decoder sowie andere Encoder/Decoder keine unsicheren Sprachen verwenden würden, wäre die Wahrscheinlichkeit deutlich geringer, solche Bugs zu erzeugen.
Unabhängig davon sehe ich auch eine Kultur als Problem, die Code unnötig komplex macht, sowie Entwickler, die die Details nicht richtig verstehen.
Dieser Fix ist in den heutigen Versionen Firefox 117.0.1 und Fenix 117.1.0 enthalten: https://hg.mozilla.org/releases/mozilla-release/rev/e245ca21...
Zur Einordnung: Im image-Crate gibt es eine in sicherem Rust geschriebene WebP-Decoder-Implementierung: https://github.com/image-rs/image
Lange Zeit war sie recht unvollständig, aber im vergangenen Jahr wurden viele WebP-Funktionen implementiert.
Chromium hat inzwischen eine Policy, die die Nutzung von Rust-Abhängigkeiten erlaubt; könnte Chromium also nicht anfangen, sie einzuführen?
Der ursprüngliche Commit, der das Problem verursachte: https://github.com/webmproject/libwebp/commit/f75dfbf23d1df1...
Der Commit, der diesen Bug behebt: https://github.com/webmproject/libwebp/commit/902bc919033134...
Der ursprüngliche Commit optimierte den Huffman-Decoder. Dieser Decoder nutzt eine bekannte Optimierung: Er liest vorab N Bits und entscheidet dann, wie viele Bits tatsächlich verbraucht werden müssen und welches Symbol zu decodieren ist. Oder, wenn es sich um ein N-Bit-Präfix mehrerer Symbole handelt, welche Tabelle für die verbleibenden Bits heranzuziehen ist.
Die alte Version verwendete für kurze Symbole eine Lookup-Tabelle, für lange Symbole war jedoch eine Traversierung des Graphen nötig. Die neue Version verbesserte das durch ein Array von Lookup-Tabellen. Jeder Eintrag enthält
(nbits, value), wobeinbitsdie Anzahl der zu verbrauchenden Bits ist undvaluenormalerweise das Symbol. Wennnbitsjedoch größer als N ist, wirdvalueals Tabellenindex interpretiert, undnbitswird als längste Codelänge in diesem Teilbaum neu interpretiert. Daher muss jede nachfolgende Tabelle2^(nbits - N)Einträge haben. Die Root-Tabelle ist immer fest auf2^NEinträge gesetzt.Die neue Version berechnete die maximale Anzahl von Einträgen (
kTableSize) anhand der Anzahl der Symbole. Natürlich stammt der Huffman-Baum aus nicht vertrauenswürdiger Eingabe, und man kann sich leicht vorstellen, dassnbitssehr groß wird. VP8 Lossless erlaubt konkret bis zu 15 Bits, sodass die maximal mögliche Tabelle2^N + 2^15Einträge groß wird, wenn alle LUTs jeweils auf eine eigene Hilfstabelle abgebildet werden. Dafür braucht man nicht einmal besonders viele Symbole; pro Tabelle reichen16-NSymbole.Interessanterweise hatte der Code selbst einen Modus, der nur die Tabellengröße berechnet (Aufruf von
VP8LBuildHuffmanTablemitroot_table == NULL), wurde aber aus irgendeinem Grund nicht verwendet und ging von einer festen Maximalgröße aus. Wenn man also einen Huffman-Baum so konstruiert, dass die Anzahl der Einträge maximiert wird, schreibt man über den zugewiesenen Bereich hinaus.Es ist nachvollziehbar, warum das passiert ist. Die Huffman-Decodierung ist in vielen Kompressionsformaten einer der rechenintensivsten Teile, daher zählen selbst kleine Verbesserungen. Die obige Optimierung ist bekannt, doch lange Codepfade gelten im Allgemeinen als selten und hatten daher eine niedrigere Optimierungspriorität. Die ursprüngliche Commit-Message widerlegte diese Annahme und konnte gemergt werden. Ich bin mir nicht sicher, ob eine speichersichere Sprache dieses Problem verhindert hätte. Denn dies ist einer der seltenen Fälle, in denen man Overflow-Prüfungen aktiv vermeiden möchte.
[1] Da die Speicherbeschädigung jedoch nicht in der engen Schleife, sondern beim Aufbau der Tabelle auftritt, hätten teilweise Overflow-Prüfungen sehr geholfen. Der eigentliche Fix hat die Funktion
ReadSymbolüberhaupt nicht geändert. Trotzdem muss die Sicherheit enger Schleifen gerechtfertigt werden, und eine falsche Rechtfertigung kann alles ruinieren.Wenn die Aussage stimmt, dass keine Bounds-Checks nötig sind, ist das in Ordnung. WUFFS gibt keine Bounds-Checks zur Laufzeit aus.
Wenn die Software jedoch wie hier falsch ist, weil sie Grenzen überschreitet, kompiliert sie in WUFFS nicht.
Man könnte denken: „Das ist unmöglich“, und wenn WUFFS eine universelle Programmiersprache wäre, würde das stimmen. Nach dem Satz von Rice ist jede nichttriviale semantische Eigenschaft unentscheidbar.
Zum Glück ist WUFFS keine universelle Sprache. Die meiste Software lässt sich nicht in WUFFS schreiben, aber Bild-Codecs schon.
Allerdings frage ich mich, ob man automatisierte Tests hätte erstellen können, die diese Art von Problem finden.
In Code, mit dem ich persönlich zu tun habe, kann ich manche Berechnungen in separate Funktionen auslagern und unabhängig testen. Hier wäre das aus Performance-Gründen vielleicht schwierig gewesen, aber sicher bin ich mir nicht.
Behebung eines Out-of-Bounds-Writes in
BuildHuffmanTablehttps://github.com/webmproject/libwebp/commit/902bc919033134...
Das könnte bedeuten, dass Google den Fuzzer für libwebp optimiert hat, nachdem dieser Bug gefunden wurde, und dadurch weitere Bugs findet.
Es sieht so aus, als sei dies von Apple gemeldet worden, und es ähnelt diesem Sicherheitsupdate sehr: https://support.apple.com/en-us/HT213906
Daher wirkt das ziemlich wahrscheinlich. Apple nutzt intern möglicherweise libwebp in ImageIO, oder sie haben einen ähnlichen Fehler gemacht.
Bild-Codecs haben eine lange Geschichte von Schwachstellen.
Die eigentliche Bildverarbeitung kann sauberer linearer Code sein, den man sogar in speichersicherem FORTRAN IV schreiben könnte, aber sobald Kompression ins Spiel kommt, gibt es viele Datenstrukturen variabler Länge, Pointer-Verfolgung usw.
Dazu kommt der Druck, dass alles schnell laufen muss.
Betrifft das auch Electron? Wenn ja, welche Versionen?
Interessant ist, dass Signal Desktop, das intern Electron nutzt, unter Linux ohne Sandbox ausgeführt wird [1][2]
[0] https://github.com/electron/electron/pull/39824
[1] https://github.com/signalapp/Signal-Desktop/issues/5195
[2] https://github.com/signalapp/Signal-Desktop/pull/4381
Gibt es einen realistischen Weg, das auszunutzen?
Soweit ich gehört habe, ist Heap Spraying auf 64-Bit nicht mehr praktikabel
Gibt es im Speicher ein vorhersagbares Objekt, das man überschreiben kann?
Auch auf 64-Bit wird Heap Spraying bei Kernel-Exploits offenbar weiterhin eingesetzt. Ich weiß nicht genau, welche Primitives Leute bei V8-Exploits verwenden