1 Punkte von GN⁺ 2023-09-13 | 1 Kommentare | Auf WhatsApp teilen
  • 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

1 Kommentare

 
GN⁺ 2023-09-13
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.

    • Natürlich sieht die Sache anders aus, wenn es dazu einen passenden Sandbox-Escape-Exploit gibt.
      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.
    • Im modernen Internet gibt es enorm viele von Nutzern hochgeladene Bilder; allein die Rechte im Benutzerkontext einer einzelnen Website zu erlangen, ist daher schon erheblich.
      Weil es nicht an eine bestimmte Site oder ein bestimmtes Frontend gebunden ist, ähnelt es eher einem verstärkten XSS.
    • Ich nutze verlustfreies WebP, und es ist deutlich effizienter als PNG.
      Ah, ich habe im falschen Thread geantwortet; eigentlich wollte ich auf „jpeg is good enough“ in https://news.ycombinator.com/item?id=37479576 antworten.
    • Bedeutet das, dass der Renderer keine Informationen an die Website zurücksenden kann?
      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.

    • Firefox hat eine zusätzliche Sandbox-Ebene, die nicht nur auf ganze Prozesse, sondern auf einzelne Bibliotheken angewendet werden kann: https://hacks.mozilla.org/2021/12/webassembly-and-back-again...
    • Fairerweise muss man sagen, dass Probleme in JPEG-Decoding-Bibliotheken in der Vergangenheit ebenfalls als Verbreitungsweg für Malware genutzt wurden.
      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.
    • Wäre dieser Bug gefunden worden, wenn Browser das neue Format nicht übernommen hätten?
      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.
    • Ursache der Sicherheitslücke ist nicht das neue Bildformat, sondern die fehlende Speichersicherheit in C/C++.
      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.
    • WebP ist ein deutlich komplexeres Format als JPEG, und Komplexität korreliert nahezu direkt mit der Fehlerdichte.
      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?

    • Wenn es in Chrome einen Flag gäbe wie „sichere Version der XYZ-Bibliothek verwenden, auch wenn sie langsam sein kann“, würde ich ihn sofort aktivieren und den Performanceverlust in Kauf nehmen.
    • Dass man 2023 bei einem Ziel mit einer so riesigen Angriffsfläche wie einem Webbrowser weiterhin neuen C/C++-Code schreibt, fühlt sich absurd an.
  • 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), wobei nbits die Anzahl der zu verbrauchenden Bits ist und value normalerweise das Symbol. Wenn nbits jedoch größer als N ist, wird value als Tabellenindex interpretiert, und nbits wird als längste Codelänge in diesem Teilbaum neu interpretiert. Daher muss jede nachfolgende Tabelle 2^(nbits - N) Einträge haben. Die Root-Tabelle ist immer fest auf 2^N Einträ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, dass nbits sehr groß wird. VP8 Lossless erlaubt konkret bis zu 15 Bits, sodass die maximal mögliche Tabelle 2^N + 2^15 Einträge groß wird, wenn alle LUTs jeweils auf eine eigene Hilfstabelle abgebildet werden. Dafür braucht man nicht einmal besonders viele Symbole; pro Tabelle reichen 16-N Symbole.
    Interessanterweise hatte der Code selbst einen Modus, der nur die Tabellengröße berechnet (Aufruf von VP8LBuildHuffmanTable mit root_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.

    • Diese Komponente hätte in WUFFS geschrieben werden sollen.
      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.
    • Ich habe seit über zehn Jahren nicht mehr als C-Programmierer gearbeitet und war auch ursprünglich nicht besonders gut darin, aber nach der Erklärung stimme ich zu, dass Bounds-Checks das Problem erkannt hätten.
      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 BuildHuffmanTable
    https://github.com/webmproject/libwebp/commit/902bc919033134...

  • Es sieht so aus, als sei dies von Apple gemeldet worden, und es ähnelt diesem Sicherheitsupdate sehr: https://support.apple.com/en-us/HT213906

    • Gemeldet wurde es von Apple und dem „Citizen Lab der UoT Munk School“, und auf der verlinkten Seite steht es genau so.
      Daher wirkt das ziemlich wahrscheinlich. Apple nutzt intern möglicherweise libwebp in ImageIO, oder sie haben einen ähnlichen Fehler gemacht.
    • Interessant zu sehen, wie unterschiedlich die Reaktionen von letzter Woche und jetzt sind.
  • 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?

  • 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?

    • Da es bereits in freier Wildbahn ausgenutzt wird, lautet die Antwort: ja
      Auch auf 64-Bit wird Heap Spraying bei Kernel-Exploits offenbar weiterhin eingesetzt. Ich weiß nicht genau, welche Primitives Leute bei V8-Exploits verwenden