2 Punkte von GN⁺ 2023-09-23 | 1 Kommentare | Auf WhatsApp teilen
  • Die einzige Sicherheitskorrektur im stabilen Chrome-Update, CVE-2023-4863, ist ein Heap-Buffer-Overflow in der WebP-Bildbibliothek; Google gab an, dass bereits ein Exploit in freier Wildbahn existiert
  • Apples Meldung vom 6. September 2023 durch SEAR, Apples CVE-2023-41064 und die Hinweise rund um BLASTPASS von Citizen Lab deuten stark darauf hin, dass es sich um denselben Bug handeln könnte
  • Die Schwachstelle wurde als Problem analysiert, bei dem während des Aufbaus der Huffman-Tabelle für die verlustfreie WebP-Komprimierung VP8L über die vorab berechnete Puffergröße hinaus geschrieben werden konnte
  • Dass gewöhnliches Fuzzing den Fehler leicht übersehen konnte, lag an den heiklen Trigger-Bedingungen: Mehrere Huffman-Tabellen maximaler Größe und eine bestimmte ungültige Tabelle mussten in genau dieser Reihenfolge erzeugt werden
  • Der upstream-Patch für libwebp wirkt ausreichend, aber da libwebp breit in Browsern, Betriebssystemen und Apps eingesetzt wird, sind Patch-Verbreitung und Sandboxing entscheidend

Warum der Chrome-Patch mit BLASTPASS zusammenhängt

  • Google behob Anfang September 2023 im stabilen Chrome-Update CVE-2023-4863, gemeldet von Apple Security Engineering and Architecture (SEAR)
    • Die Schwachstelle ist ein Heap-Buffer-Overflow in der WebP-Bildbibliothek
    • Google erklärte, man wisse von einem „Exploit für CVE-2023-4863, der in freier Wildbahn existiert“
  • Zur selben Zeit entdeckte Citizen Lab verdächtiges Verhalten auf dem iPhone einer Person aus einer in Washington, DC ansässigen zivilgesellschaftlichen Organisation
    • BLASTPASS wird mit einem iMessage-Zero-Click-Zero-Day-Exploit in Verbindung gebracht, der die Pegasus-Spyware der NSO Group verteilte
    • Nachdem Citizen Lab die Ergebnisse seiner technischen Analyse an Apple weitergegeben hatte, veröffentlichte Apple am 7. September in einer Sicherheitsmitteilung zwei CVEs
  • Apples erste CVE, CVE-2023-41061, passt zu Hinweisen darauf, dass ein Bild-Exploit in einen PassKit-Anhang eingebettet wurde, um die BlastDoor-Sandbox von iMessage zu umgehen
    • Das bösartige Bild scheint in einem anderen Prozess ohne Sandbox verarbeitet worden zu sein
  • Die zweite CVE, CVE-2023-41064, ist eine Buffer-Overflow-Schwachstelle in Apple ImageIO
    • ImageIO ist Apples Framework zum Parsen von Bildern, das verschiedene Bildformate erkennt und an den passenden Decoder weiterleitet
    • Mangels technischer Details ist nicht bekannt, welches Bildformat von CVE-2023-41064 betroffen ist
  • Da Apple ImageIO erst kürzlich WebP-Unterstützung hinzugefügt hatte, Apples Sicherheitsteam am 6. September eine WebP-Schwachstelle an Chrome meldete und Google innerhalb von fünf Tagen einen Notfall-Patch veröffentlichte und die Lücke als aktiv ausgenutzt markierte, ist es sehr wahrscheinlich, dass BLASTPASS und CVE-2023-4863 derselbe Bug sind

Wohin der libwebp-Patch auf die Schwachstelle zeigt

  • Vergleicht man die Bug-ID aus der Chrome-Sicherheitsmitteilung mit dem Open-Source-Commit in libwebp, entspricht der Patch Fix OOB write in BuildHuffmanTable CVE-2023-4863
    • Der Patch wurde am 7. September 2023 erstellt, also einen Tag nach Apples Meldung
  • Die Schwachstelle steckt in VP8L, WebPs Unterstützung für verlustfreie Komprimierung
    • Die verlustfreie WebP-Komprimierung verwendet Huffman coding, um Pixel mit 100% Genauigkeit zu speichern und wiederherzustellen
    • Moderne Implementierungen optimieren das Decoding mit Tabellen statt mit einer konzeptionellen Baumstruktur
  • Die verwundbare Version allokierte Speicher anhand einer vorab berechneten Puffergröße aus festen Tabellen und baute dann die Huffman-Tabelle direkt in diesen Bereich
    • Die neue Version berechnet in einem ersten Durchlauf die insgesamt für die Ausgabetabelle nötige Größe, schreibt dabei aber noch nichts
    • Wenn die Gesamtgröße die vorab berechnete Puffergröße übersteigt, wird stattdessen eine größere Allokation erzeugt
  • Der zentrale Ablauf betrifft huffman_tables, das in ReadHuffmanCodes in src/dec/vp8l_dec.c allokiert wird, sowie die Aufrufe von VP8LBuildHuffmanTable/BuildHuffmanTable in ReadHuffmanCode
    • Die Huffman-Tabelle ist in fünf Segmente mit unterschiedlichen Alphabetgrößen aufgeteilt
    • Um den Overflow auszulösen, mussten alle fünf Tabellen gezielt konstruiert werden

Wie die Trigger-Datei erzeugt wurde

  • Die verlustfreie WebP-Komprimierung weist auf Grundlage einer Häufigkeitsanalyse der Eingabepixel häufigen Werten kurze Bitfolgen und seltenen Werten lange Bitfolgen zu
    • Die Codes sind so konstruiert, dass der Decoder die Bitfolgenlängen stets unterscheiden kann
    • Das komprimierte Bild muss statistische Informationen und Angaben zur Code-Zuweisung enthalten, damit sich die Zuordnung von Codes zu Werten rekonstruieren lässt
  • WebP komprimiert auch die Huffman-Tabellen selbst wieder mit Huffman coding, um die Dateigröße zu verringern
    • Dadurch wurde die Analyse und das Triggern der Schwachstelle kompliziert
  • @mistymntncop stellte Harness-Code bereit, der formal gültige WebP-Dateien mit beliebigen Huffman-coding-Daten, also code lengths, erzeugt
    • Mit diesem Harness ließ sich ein beliebiges code_lengths-Array an den gewünschten Aufruf von BuildHuffmanTable übergeben
  • Bei manuellen Experimenten war das Zusammenspiel zwischen dem Histogramm innerhalb von BuildHuffmanTable, num_open, num_nodes und dem key-Wert, der die Startposition von ReplicateValue verfolgt, äußerst komplex
    • Die Root-Tabelle von count[0] bis count[8] hat keinen direkt großen Einfluss auf total_size, kann aber spätere interne Zustände verändern
    • Die Second-Level-Tabellen von count[9] bis count[15] wirken sich direkt auf die endgültige total_size aus
  • Mark Adlers enough.c gibt für Alphabetgröße, Root-Tabellengröße und maximale Code-Länge das Histogramm der maximal möglichen Lookup-Tabelle eines Huffman-Baums aus
    • In einem Kommentar steht, dass libwebps kTableSize mit diesem Tool berechnet wurde
    • Mit dem Tool ließ sich die vorab berechnete Puffergröße reproduzieren, und mit dem Werkzeug von @mistymntncop wurde bestätigt, dass die von „enough“ erzeugten code lengths die Allokation von huffman_tables zu 100% ausfüllen

Unter welchen Bedingungen der tatsächliche Overflow auftritt

  • Das Tool enough berechnet das Maximum für gültige und vollständige Codes
    • Bei einer der kleineren Tabellen mit Symbolgröße 40, 8-Bit-Root-Tabelle und maximaler Code-Länge 15 liegt die Maximalgröße bei 410
    • Es wurde kein Fall gefunden, in dem Codes, die BuildHuffmanTable als gültig akzeptiert, eine Größe über 410 erzeugen
  • Der Overflow entsteht nicht durch ausschließlich gültige Huffman-Bäume, sondern beim Einfügen eines ungültigen Huffman-Baums im letzten Schritt
    • Zunächst werden mit vier gültigen Huffman-Bäumen Ausgabetabellen maximaler Größe aufgebaut
    • Fügt man in die letzte Tabelle einen ungültigen Huffman-Baum ein, kann ReplicateValue vor der abschließenden Konsistenzprüfung außerhalb des Bereichs schreiben
  • Die Reproduktion erfolgt, indem man den verwundbaren libwebp-Commit 7ba44f80f3b94fc0138db159afea770ef06532a0 auscheckt, AddressSanitizer aktiviert, mit dem PoC-Code von @mistymntncop bad.webp erzeugt und die Datei mit dwebp decodiert
    • AddressSanitizer meldet in BuildHuffmanTable einen heap-buffer-overflow
    • Der gemeldete Schreibzugriff erfolgt an einer Adresse direkt hinter einem Bereich von 11816 Byte
  • Es gibt mehrere Eingaben, die huffman_tables zum Überlaufen bringen
    • Unter den gefundenen code lengths gibt es Fälle, die bis zu 400 Byte hinter das Ende der huffman_tables-Allokation schreiben
    • Auch wenn die Kontrolle über die geschriebenen Werte nur teilweise möglich ist, scheint eine Ausnutzung realistisch
  • Der Huffman-Baum der ungültigen Eingabe ist teilweise unausgewogen und enthält in einem Abschnitt des unausgewogenen Zweigs viele interne Knoten ohne Kinder
    • Diese Struktur erzeugt key-Indizes, die mit gültigen Bäumen nicht erreichbar sind

Wie der Patch den Overflow verhindert

  • Zunächst wirkte es so, als würde der Patch den Heap-Overflow verhindern, indem er den Puffer dynamisch auf die benötigte Größe vergrößert
  • Tatsächlich lässt die gepatchte Version BuildHuffmanTable in einem ersten Durchlauf die gesamte benötigte Größe berechnen, ohne in die Tabelle zu schreiben
    • Bei den ungültigen Eingaben, die den Overflow auslösten, schlägt BuildHuffmanTable bereits in diesem ersten Durchlauf fehl und gibt 0 zurück
    • Da der erste Durchlauf nichts schreibt, entsteht selbst bei teilweiser Verarbeitung des ungültigen Baums kein Out-of-Bounds-Write
  • Da kein gültiger und vollständiger Code gefunden wurde, der denselben Overflow auslöst, wirkt dieser Patch ausreichend

Warum Fuzzing den Fehler leicht übersehen konnte

  • libwebp wurde lange über Google OSS-Fuzz gefuzzt, und auch die Unterstützung für verlustfreies WebP wurde umfassend gefuzzt
  • Die zentrale Schwierigkeit liegt darin, dass sowohl das Format als auch die Trigger-Bedingungen komplex sind
    • Unter Milliarden möglicher Varianten müssen zunächst vier Huffman-Tabellen maximaler Größe für die Alphabetgrößen 280 und 256 aufgebaut werden
    • Danach muss für die Alphabetgröße 40 ein ungültiger Huffman-Baum mit sehr spezifischer Form erzeugt werden
    • Schon ein einziges falsches Bit in irgendeinem Schritt führt dazu, dass der Bilddecoder mit einem Fehler sauber abbricht
  • Google veröffentlichte nach dem Fix des WebP-0day einen neuen Fuzzer speziell für die WebP-Huffman-Routinen
    • Selbst mit diesem Fuzzer wurde CVE-2023-4863 nicht gefunden
  • Standardmäßige Bitflip-Mutationen, Code-Coverage-Feedback-Schleifen und eingabezustandsbasierte Ansätze wie CmpLog von AFL++ tun sich schwer, bei diesen extremen Zuständen die Zwischenschritte zu passieren
    • Dynamische symbolische Ausführung wie TritonDSE von Quarkslab könnte erfolgversprechend sein, wurde aber nicht verifiziert
  • Die Schwachstelle unterscheidet sich in ihrem Charakter von der Load_SBit_Png-Lücke in FreeType
    • Bei Load_SBit_Png spiegelte der Fuzzing-Harness die API-Nutzung nicht ausreichend wider, weshalb der Fehler unentdeckt blieb
    • Bei CVE-2023-4863 liegt die Schwierigkeit weniger an einem unzureichenden Harness als an den inhärenten Einschränkungen der Schwachstelle selbst

Betroffener Bereich und Stand der Reaktion

  • Citizen Lab hat einen in freier Wildbahn eingesetzten fortgeschrittenen Exploit erfasst, und Apple sowie Chrome scheinen innerhalb weniger Tage Updates an Milliarden Nutzer ausgeliefert zu haben
  • Android könnte zu diesem Zeitpunkt noch betroffen gewesen sein
    • Androids BitmapFactory verarbeitet ähnlich wie Apple ImageIO die Bilddecodierung und unterstützt libwebp
    • Die damalige Android-Sicherheitsmitteilung enthielt noch keinen Fix für CVE-2023-4863, die Korrektur war jedoch bereits in AOSP gemergt
    • Falls Android betroffen ist, könnte dies zu Remote-Exploits in Apps wie Signal oder WhatsApp führen
    • Mit einem Fix wurde in der Sicherheitsmitteilung für Oktober gerechnet
  • Der upstream-Patch für libwebp scheint korrekt angewendet worden zu sein und verbreitet sich nun an die nötigen Stellen
  • Da libwebp an vielen Orten verwendet wird, kann es dauern, bis der Patch überall ausreichend ausgerollt ist
  • Bei komplexem Parser-Code wie der Bilddecodierung, der nahe an Zero-Click-Remote-Exploit-Angriffsflächen liegt, reicht Fuzzing allein kaum aus, um Sicherheit zu garantieren; nötig sind proaktive Source-Code-Reviews und angemessene Investitionen in Sandboxing

Asymmetrie bei der Offenlegung technischer Informationen

  • Wenn Hersteller nicht genügend technische Details veröffentlichen, können Verteidiger die Auswirkungen einer Schwachstelle nur schwer verifizieren
  • Angreifer haben starke Anreize, N-Day-Schwachstellen nachzuverfolgen und auszunutzen, und werden durch fehlende öffentliche Details meist nicht wesentlich aufgehalten
  • Verteidigern fehlen oft die Ressourcen, um technische Analysen auf diesem Niveau selbst durchzuführen
  • Werden selbst grundlegende Informationen zum Angriffsverhalten zurückgehalten, entsteht eine Asymmetrie, bei der Angreifer mehr Einblick in Schwachstellen und Exploits haben als Verteidiger

1 Kommentare

 
GN⁺ 2023-09-23
Meinungen auf Hacker News
  • Dieser Bug wirkt dem Timsort-Bug von 2015 am ähnlichsten [1]
    Timsort ist ein cleverer hybrider Sortieralgorithmus aus CPython, und mehrere Implementierungen, darunter OpenJDK, haben ihn praktisch als Übersetzung auf Quellcode-Ebene übernommen. Er verwaltet einen Stack sortierter Runs, und es gab einen Beweis, dass die strukturell mögliche maximale Stack-Größe eine ausreichend kleine endliche Obergrenze hat. Die ursprüngliche CPython-Implementierung passte jedoch nicht exakt zum Beweis, sodass in seltenen Fällen ein Stack-Overflow möglich war. In CPython war das daher ein schwerer Security-Bug, während Java in diesem Fall eine Exception warf und es in OpenJDK nicht auf dieselbe Weise ein Sicherheitsproblem war
    Ähnlich entstand auch dieser WebP-Bug, weil die maximale Tabellengröße zwar formal bewiesen war, aber nicht zu dem Wert passte, der tatsächlich im Quellcode stand. Solche Bugs sind schwer zu verifizieren und schwer zu reviewen. Es ist leicht zu denken, alles sei in Ordnung, weil es einen Beweis gibt und der Source scheinbar dazu passt. Das wirkt wie ein starkes Signal dafür, dass wir zugängliche formale Verifikation statt menschlicher Reviews und außerdem speichersichere Sprachen brauchen. Auch Typsysteme kann man als schwache Form formaler Verifikation betrachten
    [1] http://envisage-project.eu/wp-content/uploads/2015/02/sortin...

    • Für solche Arbeit, bei der Performance wichtig ist, sollte man insbesondere WUFFS verwenden. WUFFS gibt keine Bounds-Checks aus wie Java und prüft auch nicht wie Rust zur Laufzeit, wenn unklar ist, ob ein Index im gültigen Bereich liegt. Stattdessen lehnt es das Programm selbst ab, wenn das Tool nicht bestätigen kann, dass der Index innerhalb der Grenzen liegt
      https://github.com/google/wuffs
      Man kann dieselbe Prüfung auch explizit schreiben und so diese Anforderung erfüllen. Wenn man aber glaubte, dass bei High-Performance-Software keine Prüfung nötig sei, ist die Wahrscheinlichkeit groß, dass man genau an der Stelle, an der das WUFFS-Tool den Code nicht akzeptiert, feststellt, dass man falschlag. Das ist schwächer als vollständige formale Verifikation, aber für das Ziel der Programmsicherheit eine große Verbesserung und viel besser als ein menschliches „LGTM“
    • Ob „Typsysteme als schwache formale Verifikation gelten können“, hängt von der Art des Typsystems ab. Ich habe mir kürzlich Idris angesehen; es scheint eine Allzweck-Programmiersprache zu sein, die man auch für Beweise verwenden kann
  • Neben der Frage „Was muss jetzt gepatcht werden?“ gab es in diesem Artikel einige interessante Punkte. Selbst wenn man die Stelle der Schwachstelle und die Korrektur kennt, kann es noch einiges an Arbeit sein, einen Exploit-PoC zu reproduzieren, und ein Lossless-Decompressor innerhalb eines Image-Decoders kann ziemlich fuzzing-resistent sein. Für Security-Leute mag das selbstverständlich sein, aber als Nicht-Experte fand ich es spannend zu lesen

    • Die Lösung für solche Probleme ist nicht Fuzzing, sondern den betreffenden Code wie einen Tumor herauszuschneiden. Wenn dadurch an verschiedenen Stellen im OS oder Browser etwas kaputtgeht, schreibt man eben einen stark sandboxed, speichersicheren Formatkonverter, der das problematische Format verarbeitet. Ein iPhone oder Browser, der in einigen Edge Cases unbequem ist, ist meiner Ansicht nach besser als solcher Code, bei dem Schwachstellen nahezu garantiert sind, egal ob gefuzzt wurde oder nicht. Das ist zwar optimistisch formuliert, aber ich bin sicher, dass diese Geschichte hier nicht enden wird
  • Ich habe ein paar Fragen, auf die ich keine klare Antwort finde. 1) Sind auch andere Chrome-basierte Browser wie Brave betroffen? 2) Ist auch Desktop-Chrome betroffen, oder ist das nur ein mobiles Problem? 3) Warum habe ich noch nie von WebP gehört? Ich frage mich, ob ich von der Welt abgeschnitten war oder ob es eine Mobile-First-Technik ist

    • Gute Fragen. Andere Chromium-basierte Browser sind sehr wahrscheinlich ebenfalls von diesem Bug betroffen. Viele Browser wie Brave ziehen Chromium-Sicherheitsupdates gut nach, aber es gibt auch Fälle wie Samsung SBrowser, die ziemlich hinterherhinken
      Desktop-Chrome war ebenfalls betroffen, sowohl unter Linux als auch unter Windows. Chrome bündelt seine eigene libwebp; selbst wenn eine Linux-Distribution noch nicht gepatcht hat, ist man bei aktuellem Chrome zumindest hinsichtlich Browser-Angriffen in Ordnung
      Große Browser und Betriebssysteme unterstützen erstaunlich viele eher unbekannte Bildformate. Unter macOS kann man zum Beispiel KTX2 (Khronos Texture Container) laden, unter Android DNG (Adobe Digital Negative). Es gibt viele interessante und stark exponierte Angriffsflächen, die Angreifer erkunden können
    • Betroffen ist alles, was WebP unterstützt. Nicht nur Chrome oder Electron, sondern alle Browser, Desktop und Mobile, sowie auch Software außerhalb des Browsers. Dazu gehören Bildbetrachter, Grafikprogramme, E-Mail-Clients und sogar Dateimanager, die Thumbnails anzeigen
      Der Bug steckt in der Codec-Bibliothek, und WebP hat ein faktisch vereinheitlichtes Implementierungs-Ökosystem: Alle verwenden dieselbe Bibliothek, und alle müssen gepatcht werden
      Google hat WebP vor zehn Jahren vorangetrieben, aber lange blieb es Chrome-exklusiv und konnte deshalb nicht richtig an Fahrt gewinnen. Es wurde auch nie ordentlich standardisiert, ist aber Open Source. Bei Bildern niedriger Qualität komprimiert es besser als JPEG, bei hochwertigen Bildern neigt es jedoch dazu, Farben ausbluten zu lassen und unscharf zu wirken. Ironischerweise war WebP zu dem Zeitpunkt, als es breit unterstützt wurde, durch AVIF und JPEG XL technisch bereits dabei, veraltet zu werden
    • Du hast mit ziemlicher Sicherheit schon WebP-Bilder heruntergeladen und angesehen, es aber vermutlich nicht bemerkt, weil viele Websites unter derselben URL mehrere Formate ausliefern. Üblicherweise konvertiert ein HTTP-Reverse-Proxy das Format automatisch, sodass ein Browser aus den letzten zehn Jahren WebP bekommen kann, selbst wenn die Dateiendung beim Download wie „.png“ aussieht. Moderne Bildbearbeitungen unterstützen alle WebP, daher ist der Unterschied schwer zu bemerken
    • WebP wird in Desktop-Chrome schon seit langer Zeit unterstützt. Dutzende JPEG-Ersatzformate sind gekommen und gegangen; bei WebP sticht vor allem hervor, dass Googles Einfluss dahinterstand. Als Google Duck/On2 übernahm, bekam es viele Videokompressionstechniken, und ein Teil davon floss in WebP ein
    • Alle Browser sind betroffen, und auch Firefox hat ein Sicherheitsupdate veröffentlicht. WebP wird als JPEG-Ersatz immer beliebter, daher ist es überraschend, wenn du ihm noch nicht begegnet bist, wenn man bedenkt, dass heruntergeladene Bilder im Web zunehmend als WebP ausgeliefert werden
  • Wenn ein Android-Gerät nicht mehr unterstützt wird, ist es dann faktisch einem derzeit aktiv kursierenden 0-Click-Exploit ausgesetzt? Oder reicht es, SMS-App, Chrome, WhatsApp, Signal usw. zu aktualisieren, um die wichtigsten Eingangswege ausreichend zu schließen?

    • Ob es für diesen Bug bereits einen Android-Exploit gibt, ist nicht sicher. Der ursprüngliche Exploit war für iOS über iMessage, aber die Wahrscheinlichkeit ist ziemlich hoch, dass bereits einer entwickelt wurde. Die Nachfrage nach solchen Exploits für Android ist derzeit sehr groß, und ich habe zuletzt von absurden Preisen gehört.
      Wenn man Chrome auf nicht mehr unterstützten Geräten aktualisiert, ist das Chrome-Problem behoben; um Apps wie Signal oder WhatsApp zu reparieren, braucht es jedoch ein Android-OS-Upgrade. Chrome bündelt seine eigene libwebp, aber exponierte Apps wie Messaging-Apps und Gmail verwenden für die Bildanzeige vom OS bereitgestellte Schnittstellen. Bei Android-Geräten mit Sicherheits-Support rechne ich ab Anfang Oktober mit Updates.
    • Die Bild-Dekodierungsbibliothek der Plattform sollte eines der Systemmodule sein, die über den Play Store aktualisiert werden. Ich frage mich, ob jemand bestätigen kann, ob das tatsächlich so ist.
    • Einige Messaging-Apps haben eine Option, empfangene Bilder nicht automatisch herunterzuladen oder als Vorschau anzuzeigen; diese Einstellung zu aktivieren, könnte eine gute Maßnahme sein. Google Messages hat diese Funktion.
    • Wenn Android keine Sicherheitsupdates mehr bekommt, ist das nicht das Einzige, worüber man sich Sorgen machen muss. Ich würde mich zuerst um die leichter auszunutzenden Dinge kümmern.
    • Unter iOS ist das besonders problematisch, weil iMessage hohe Rechte hat. Unter Android laufen solche Apps alle in einer Sandbox.
  • „Es gibt viele Eingaben, die huffman_tables tatsächlich zum Überlaufen bringen“ klingt nach einem allgemeineren Problem. Software A erzeugt eine Lookup-Tabelle B, und diese Tabelle wird zur Verarbeitung eines Eingabedatenstroms verwendet.
    Jeder Entwickler, dem Sicherheit oder Korrektheit auch nur ein wenig wichtig ist, muss nun eines von zwei Dingen garantieren: A) Die Software ist so geschrieben, dass keine Eingabedaten die Lookup-Tabelle missbrauchen oder zum Fehlschlagen bringen können, oder B) sie wird nur in einer kontrollierten Umgebung eingesetzt, etwa in einer Punkt-zu-Punkt-Kommunikation, bei der beide Kommunikationsparteien vertrauenswürdig sind, sodass garantiert ist, dass der Stream die Lookup-Tabelle niemals missbraucht oder Abweichungen verursacht.
    B ist außer in kleinen Gruppen oder Büros kaum möglich, und im Internetmaßstab wirklich unmöglich; am Ende bleibt also nur A. Eine allgemeine Best Practice der künftigen Softwaretechnik sollte sein: Wenn aus irgendeinem Grund eine Lookup-Tabelle verwendet wird, muss der Entwickler sicherstellen, dass diese Tabelle für alle Datentypen korrekt funktioniert, oder fehlerhafte Daten erkennen und angemessen behandeln, bevor sie die Tabelle erreichen.
    Wenn ich ein ernsthafter Sicherheitsforscher wäre und Zeit hätte, würde ich eine Liste aller früheren Sicherheitslücken zusammentragen, die irgendwie mit Lookup-Tabellen zu tun hatten, sie eine nach der anderen lesen und die Gemeinsamkeiten vergleichen. Vermutlich gibt es ein Muster. Danach würde ich jede Software durchgehen, die Lookup-Tabellen für Datenströme verwendet, und auf Schwachstellen auditieren — aber das ist nichts, was eine einzelne Person in einem Leben schaffen kann, sondern ein Teamsport.

  • In welchem Maß hat offener Quellcode NSO wohl dabei geholfen, diesen Bug zu finden? Wenn der Code nur ein Binary Blob gewesen wäre, frage ich mich, ob moderne Decompiler allein ausgereicht hätten, um den Code zu verstehen und einen so schwer greifbaren Bug zu finden.

    • Blobs halten Angreifer nicht auf. Um einen erfolgreichen Exploit zu schreiben, muss man ohnehin das kompilierte Binary verstehen.
  • Überraschend ist, dass es kein „neuer“ Teil des Bildformats ist. Huffman-Kompression gibt es seit über 70 Jahren, kanonisches Huffman nur ein paar Jahrzehnte weniger, und selbst JPEG nutzt Huffman. Das ist jahrzehntealte Technik, zu deren Implementierung es unzählige Texte gibt; eigentlich wirkt es wie eine Technik, bei der die Bugs in den verschiedenen Implementierungen inzwischen ausgeräumt sein sollten.
    Ich habe vor Jahren die JPEG-Spezifikation gelesen und auch einen Decoder geschrieben, also habe ich mir die WebP-Spezifikation angesehen: https://developers.google.com/speed/webp/docs/webp_lossless_...
    Das Wichtige steht in Abschnitt 6. Was zuerst auffällt: Anders als in der JPEG-Spezifikation ist nicht klar beschrieben, wie die Codes aufgebaut sind. JPEG enthält viele gut lesbare Ablaufdiagramme für den Prozess. WebP sieht eher nach LZH/deflate (zlib) aus und wirkt weniger wie eine „Spezifikation“ als wie eine Sammlung kommentierter Ausschnitte aus Quellcode.
    Nach GIF-, JPEG- und PNG-Decodern überlege ich zwar, auch einen WebP-Decoder zu schreiben, aber allein anhand der obigen „Spezifikation“ fühlt es sich fast so an, als solle man es lieber lassen.

    • Ich stimme zu, dass der Spezifikation wirklich Beispiele fehlen, aber sie sagt ausdrücklich, dass ein kanonischer Huffman-Baum verwendet wird und daher nur die Codelängen übertragen werden müssen. Das ist meiner Ansicht nach ausreichend eindeutig, um den tatsächlichen Baum festzulegen. Eine kanonische Huffman-Implementierung, die umgekehrte lexikografische Reihenfolge verwendet, dürfte es wohl nicht geben.
      Bei Implementierungen von Huffman-Bäumen gibt es viele unterschiedliche Trade-offs; nur weil die Technik alt ist, heißt das daher nicht, dass alle Bugs ausgeräumt sind. Charles Bloom meinte, dass selbst das maßgebliche Paper von 1997 zu Huffman-Optimierungen [1] bis 2010 nicht besonders bekannt war und viele Optimierungen wiederentdeckt und dann wieder vergessen wurden. Daher ist es gut möglich, dass es viele ineffiziente Implementierungen gibt.
      [1] https://cbloomrants.blogspot.com/2010/08/08-12-10-lost-huffm...
    • Wenn du Referenzcode brauchst: Unter https://github.com/golang/image/tree/master/vp8l gibt es einen WebP-Lossless-Decoder mit weniger als 1200 Zeilen.
  • Inzwischen scheint man nicht einmal mehr Bilder anschauen zu können, ohne sich Sicherheitsgedanken zu machen.

    • Wenn Softwareanbieter beim Rendern von Bildern eine etwas langsamere Bibliothek verwenden, lässt sich die schwerwiegendste Sicherheitsgefahr, nämlich Remote Code Execution, vermeiden. Wenn man in C geschriebene Bibliotheken meidet, kann man Remote Code Execution fast eliminieren, und Nutzer sind sicherer.
    • Vielleicht erinnere ich mich falsch, aber ich glaube, bei PNG und JPG gab es mindestens einmal etwas Ähnliches.
      Das klingt nach den typischen Wachstumsschmerzen, die entstehen, wenn man die unsichere Sprache C verwendet. Ich verstehe, dass sie wegen der Browsergeschwindigkeit attraktiv ist, aber ich wünschte, die Branche käme von dem Muster weg, dieselben Fehler zu fördern, die sie seit Beginn der Nutzung von C immer wieder macht.
      Es fühlt sich an, als würde man Brücken mit selbstschneidenden Schrauben statt mit Nieten bauen, weil das schneller ist. Wenn die Brücke anfängt durchzuhängen, schraubt man eben noch mehr Schrauben hinein.
  • „Die gute Nachricht ist, dass Apple und Chrome hervorragend auf die Dringlichkeit dieses Problems reagiert haben“ – das ist schwer nachzuvollziehen. Google war es, das dieses Problem als Chrome-spezifisch eingestuft hat. Allein in den vergangenen sieben Tagen mussten alle großen Linux-Distributionen Updates ausrollen, und Red Hat hat es mit 9,6 bewertet. Auch Python-Docker-Images mit über einer Milliarde Pulls, Puppeteer, WordPress, Node.js usw. waren betroffen, aber der CRBug ist immer noch nicht öffentlich
    Seiten wie BleepingComputer haben ohne eigene Untersuchung einfach berichtet, was sichtbar war, und viele Sicherheitsfirmen, die dieses Thema wie eine Drittpartei behandelt haben, ebenso. Wenn man weiß, dass die Gegenseite keine Due Diligence betrieben hat, ist es wirklich schwer, Vertrauen aufzubauen
    Adam Caudill hat zusammen mit dem Beispiel, dass 1Password früh gepatcht hat, einen guten Beitrag „Whose CVE is it anyway?“[0] geschrieben und darin das hier angesprochene Problem gut herausgearbeitet. Citizen Lab hat eine Antwort darauf verweigert, ob die beiden Issues zusammenhängen, aber man muss kein Genie sein, um gewisse Dinge zu erkennen
    [0]: https://adamcaudill.com/2023/09/14/whose-cve-is-it-anyway/

    • Der Grund, warum Apple und Chrome hier besonders wichtig sind, ist, dass sie die Ziele waren, die tatsächlich in freier Wildbahn ausgenutzt wurden, und die größte unmittelbare Angriffsfläche mit den meisten Nutzern haben
      Der Autor sagt ebenfalls, dass viele andere Systeme gepatcht werden müssen. Aber wie viele der Python-Docker-Images mit einer Milliarde Pulls rendern wohl nicht vertrauenswürdige WebP-Bilder? Bei Node und Ähnlichem gilt dasselbe. Natürlich muss schnell gepatcht werden, aber das ist nicht auf derselben Stufe wie iOS/Android/Chrome
  • Weltweit sind Hunderte Millionen Menschen von dieser Library betroffen, und der Einfluss vervielfacht sich noch über die jeweils genutzten Geräte und Apps
    Ich mag C, aber ich denke, Libraries, die von Hunderten Millionen Menschen weltweit genutzt werden, sollten nicht in C geschrieben werden. Bei solchen Kern-Libraries ist der Risikoanteil zu hoch. Selbst C-Experten machen irgendwann Fehler
    Das scheint der Fix zu sein: https://github.com/webmproject/libwebp/commit/dce8397fec159c...
    „malloc fail“ – frustrierend. Slack, Discord, Teams und sogar alle modernen Betriebssysteme sind betroffen

    • Der eigentliche Fix ist dieser: https://github.com/webmproject/libwebp/commit/902bc919033134...
    • Sehe ich genauso. Rust sollte das neue C werden. Nur weil man in C programmieren kann, heißt das nicht, dass man aus Gründen wie „Performance“, „Portabilität“ oder „Legacy-Kompatibilität“ massenhaft komplexen Code produzieren sollte
      C/C++ und dynamische Sprachen vergrößern die Angriffsfläche für undefiniertes Verhalten und subtile Bugs erheblich und sind selbst für die klügsten Entwickler schwer zu linten und eine große Belastung. Basis-Libraries sollten ähnlich wie seL4 formal verifiziert werden
      Ein weiteres Problem ist die im gesamten FOSS-Bereich verbreitete Unprofessionalität sowie die Missachtung von Strenge, Qualität, Korrektheit und Sicherheit. Die derzeitige Art, ein Imperium auf Sand zu bauen, ist töricht
    • Weder hier noch in den benachbarten Commits gibt es auch nur einen einzigen Test. Unfassbar