2 Punkte von GN⁺ 2024-01-07 | 1 Kommentare | Auf WhatsApp teilen
  • Der Chromium Money Tree Browser ordnet Chrome-VRP-Prämien den Änderungen in Verzeichnissen und Dateien des Chromium-Repositorys zu, sodass sich überblicken lässt, an welchen Stellen im Codebaum sich Sicherheitsprämien angesammelt haben
  • Die Prämienhöhe wird auf die Anzahl der geänderten Dateien verteilt; wenn ein mit 1.000 $ prämierter Bugfix 5 Dateien ändert, werden jeder Datei 200 $ zugewiesen
  • Die oberste Aggregation wird als root 9.873.277 $ / 10.944 Fälle, chromium 9.014.838 $ / 10.218 Fälle, chrome 2.568.260 $ / 2.574 Fälle angezeigt
  • Mehrere Bereiche wie chrome/browser/ui/views, extensions, media, safe_browsing, enterprise, Android, net, device, gpu, storage, base, iOS und pdf werden bis auf Dateiebene aufgeschlüsselt; auch V8 macht mit 858.439 $ / 726 Fällen einen großen Anteil aus
  • Es gibt den Hinweis, dass Daten und UI „very very hacked together“ seien, und der Umfang reicht nur bis Anfang November 2023; eher als Erkundungskarte denn als exakte Buchhaltungsunterlage zu verstehen

Wie die Prämien auf den Codebaum verteilt werden

  • Ein Browser, der Chrome-VRP-Bug-Bounty-Prämien mit dem Datei- und Verzeichnisbaum der Chromium-Codebasis verknüpft
    • Wenn ein bestimmter Sicherheitsfix mehrere Dateien ändert, wird die Prämie durch die Anzahl der Dateien geteilt und jeder Datei zugewiesen
    • Diese Verknüpfung dient eher dazu, zu überblicken, „welcher Code häufig zusammen mit Sicherheitsprämien verändert wurde“
  • Schon die oberste Aggregation zeigt eine beträchtliche Verteilung von Prämien über Chromium insgesamt
    • root: 9.873.277 $ / 10.944 Fälle
    • chromium: 9.014.838 $ / 10.218 Fälle
    • chrome: 2.568.260 $ / 2.574 Fälle
    • chrome/browser: 2.250.643 $ / 1.920 Fälle

Auffällige Verteilung nach Verzeichnissen

  • Unter chrome/browser/ui/views ist die Prämienverteilung fein nach UI-Funktionen für Nutzer aufgeteilt
    • views: 514.665 $ / 441 Fälle
    • tabs: 56.705 $ / 30 Fälle
    • eye_dropper: 47.000 $ / 7 Fälle
    • bookmarks: 46.697 $ / 31 Fälle
    • payments: 43.623 $ / 60 Fälle
    • media_router: 36.395 $ / 12 Fälle
    • tab_sharing: 30.591 $ / 9 Fälle
  • Auch Chrome-Erweiterungsbereiche tauchen wiederholt als größere Blöcke auf
    • extensions: 157.507 $ / 262 Fälle
    • extensions/api: 115.471 $ / 161 Fälle
    • api/tabs: 42.705 $ / 48 Fälle
    • api/debugger: 28.488 $ / 35 Fälle
    • api/downloads: 15.225 $ / 13 Fälle
    • Ein separater extensions-Bereich wird ebenfalls mit 132.615 $ / 213 Fällen ausgewiesen, einschließlich renderer, guest_view/web_view und file_system API
  • V8 wirkt in den bereitgestellten Notizen als größter einzelner Unterbereich
    • V8 insgesamt: 858.439 $ / 726 Fälle
    • v8/src: 626.845 $ / 503 Fälle
    • v8/test: 209.030 $ / 195 Fälle
    • v8/src/compiler: 151.267 $ / 85 Fälle
    • v8/src/heap: 91.891 $ / 64 Fälle
    • v8/src/builtins: 68.133 $ / 30 Fälle
    • v8/test/mjsunit: 164.644 $ / 113 Fälle
  • Im Bereich chrome/browser fallen Nutzerkontaktpunkte wie UI, Tabs, Autofill, Passwörter, DevTools und Renderer-Kontextmenüs auf
    • chrome/browser/autofill: 114.656 $ / 40 Fälle
    • chrome/browser/tabs: 92.316 $ / 25 Fälle
    • passwords: 51.060 $ / 10 Fälle
    • chrome_content_browser_client.cc: 51.512 $ / 11 Fälle
    • devtools: 48.255 $ / 35 Fälle
    • renderer_context_menu: 47.842 $ / 16 Fälle
    • printing: 42.225 $ / 14 Fälle
    • payments: 41.252 $ / 10 Fälle
  • Auch Medien-, Sicherheits-, Enterprise- und Plattformbereiche summieren sich auf hohe Beträge
    • media: 134.523 $ / 65 Fälle, separater Bereich chrome/browser/media: 89.008 $ / 34 Fälle
    • safe_browsing: 80.161 $ / 31 Fälle
    • enterprise: 59.000 $ / 38 Fälle
    • ash: 130.389 $ / 161 Fälle, ein weiterer ash-Bereich folgt mit 56.867 $ / 55 Fälle
    • mojo: 112.725 $ / 26 Fälle
    • net: 97.558 $ / 175 Fälle
    • device: 61.770 $ / 32 Fälle
    • gpu: 51.155 $ / 30 Fälle
    • storage: 48.303 $ / 66 Fälle
    • base: 36.013 $ / 27 Fälle
  • Auch Android und iOS sind in separaten Plattformbereichen aufgeteilt
    • Android chrome/browser Java-, Ressourcen- und Testbereiche: 94.441 $ / 159 Fälle
    • Android-Java-Pfad: 62.571 $ / 91 Fälle
    • Android fullscreen: 18.707 $ / 11 Fälle, FullscreenHtmlApiHandler.java: 18.540 $ / 10 Fälle
    • iOS: 33.625 $ / 86 Fälle
    • ios/chrome/browser/web: 11.663 $ / 4 Fälle
    • ios/chrome/browser/ui: 9.884 $ / 24 Fälle

Testdateien und Hinweise zur Interpretation

  • Auch Testdaten und Regressions-Testdateien sind in der Prämienverteilung enthalten
    • test: 147.193 $ / 311 Fälle
    • test/data: 116.355 $ / 271 Fälle
    • test/data/extensions/api_test: 59.337 $ / 166 Fälle
    • V8 test/mjsunit/regress: 82.180 $ / 58 Fälle
    • V8 test/mjsunit/compiler: 46.233 $ / 28 Fälle
    • Der Grund ist, dass bei Sicherheitsfixes, die zusammen mit Änderungen an Testdateien erfasst werden, auch diesen Dateien ein Teil der Prämie zugewiesen wird
  • Wegen der einfachen Berechnung lässt sich der Betrag nicht direkt als Risiko oder Ursache einer Schwachstelle lesen
    • Da die Prämie durch die „Anzahl der geänderten Dateien“ geteilt wird, bedeutet der Betrag einer einzelnen Datei nicht unmittelbar deren eigenes Risikoniveau
    • Daten und UI sind in einem Zustand „very very hacked together“, verbunden mit dem Hinweis, weder gute UX noch exakte Daten zu erwarten
    • Der Datenumfang reicht bis Anfang November 2023
  • Ein Link zur zugehörigen Diskussion wird ebenfalls bereitgestellt

1 Kommentare

 
GN⁺ 2024-01-07
Meinungen auf Hacker News
  • Das ähnelt ziemlich dem, was ich schon lange bauen wollte. Es wäre nützlich, die Wahrscheinlichkeit, dass eine bestimmte Änderung Probleme verursacht, anhand der früheren Historie zerstörerischer Änderungen in derselben Datei oder im selben Bereich einer Datei zu berechnen.
    Im Grunde würde man jeder Änderung einen Risikowert zuweisen und diesen Wert pro PR anzeigen, damit Reviewer wissen, welchen Code sie genauer ansehen sollten; auch bei Deployments würden riskante Änderungen hervorgehoben.
    Der schwierige Teil ist, denselben Codebereich weiterzuverfolgen, wenn Codepositionen durch Einfügungen/Löschungen weiter oben nach oben oder unten wandern; Algorithmen, die sich einfach auf Zeilennummern stützen, bekommen hier Probleme.
    Trotzdem scheint selbst eine Betrachtung nur auf Dateiebene, wie in diesem Beispiel, schon ausreichend nützlich zu sein.

    • Ich arbeite seit über zwei Jahren daran. Jede Änderung wird statisch analysiert, ebenso täglich das gesamte Monorepo, und dann auf Symbolebene verarbeitet.
      Bei Änderungen mit hohem Risiko lassen wir mehr Tests laufen, allerdings keine Unit-Tests, sondern Client-Tests. Manchmal stehen 100.000 Client-Tests zur Auswahl; wir priorisieren sie und führen dann nur eine kleine Teilmenge aus.
      Das ist ein schwieriges Problem. Eine interessante Beobachtung ist, dass es in der verursachenden Änderung zwar ein oder zwei verursachende Symbole gibt, deren Konnektivität aber der von nicht verursachenden Symbolen in derselben Änderung sehr ähnlich ist.
      Außerdem ist der nach einer Änderung transitiv modifizierte Call Graph ziemlich groß; Tiefe 50 ist nicht ungewöhnlich. Außer dem Grad der Überlappung transitiv beeinflusster Symbole zwischen Änderung und Tests ließ sich kaum ein nützliches Signal gewinnen.
      Datei- und Build-Target-Ebene waren zu grob; AST-Symbole funktionieren gut.
    • Man sollte nicht nur den Code selbst betrachten, sondern auch den Autor. Ich habe mit jemandem gearbeitet, der bei jedem PR mindestens einen Bug eingebaut hat.
    • Ich lese gerade ein Buch zu genau diesem Thema: https://pragprog.com/titles/atcrime/your-code-as-a-crime-sce...
    • Es wäre gut, Codeposition, Herkunft/Autor und eine Datenflussanalyse zu benachbartem sensiblen Code gemeinsam zu betrachten. Das wäre etwas für mein Review-Tool.
  • Sehr cool. Allerdings scheint einiges zu fehlen. Ich bin mir ziemlich sicher, dass es auch in third_party/ffmpeg mindestens einen Fall gab.
    Solche Fixes landen normalerweise zuerst upstream, was die Nachverfolgung erschweren kann.

    • Verwendet werden Kommentare, die Git Watcher in Monorail-Bugs hinterlässt.
  • Wenn man sich die große Sammlung unter chrome/browser/ui ansieht, denkt man darüber nach, wie viele use-after-free-Fehler in Daten auftreten, bei denen die Performance-Vorteile manueller Speicherverwaltung kaum wichtig sind. [1] ist zum Beispiel ein Problem rund um den Lebenszyklus des Dialogs „Datei auswählen“.
    Im großen Ganzen scheint es für solchen Code besser, defensiv immer klügere, wenn auch langsamere Pointer zu verwenden. Der Typ raw_ptr [3] in [2] schien genau dabei helfen zu wollen; vielleicht war der Crash in [2] tatsächlich ein Fall, in dem die Verteidigung funktioniert hat.
    Schade ist, dass es innerhalb eines Projekts keine gute Möglichkeit gibt, in einem breiteren Sinn zwischen Dialekten umzuschalten, etwa „dieser Teil ist performancekritischer und sorgfältig reviewter Code“ und „dieser Teil ist performanceunkritisch, hat viel asynchronen Zustand und ist fehleranfällig“. Ich habe sogar schon gedacht, dass es für Letzteres fast sinnvoll wäre, eine separate Sprache mit GC beizumischen.
    Nebenbei: Ich habe vor langer Zeit an diesem Code gearbeitet, und es würde mich nicht überraschen, wenn mehr als null dieser Bugs von mir stammen.
    [1] https://bugs.chromium.org/p/chromium/issues/detail?id=120103...
    [2] https://bugs.chromium.org/p/chromium/issues/detail?id=132323...
    [3] https://source.chromium.org/chromium/chromium/src/+/main:bas...

    • Das entspricht ziemlich genau der Erklärung des unsafe-Keywords in Rust.
      Und diese Art von Code war buchstäblich eine der ursprünglichen Motivationen für die Entstehung von Rust. Die Sprache wurde schließlich von Anfang an mit Blick auf Browser-Implementierungen entworfen.
    • Performancekritische Teile in C oder Rust zu schreiben und den Rest in Python zu lassen, ist im Grunde genau so ein Beispiel. Soweit ich gehört habe, sind Rust-Python-Bindings besonders gut und erleichtern es, auch in performancekritischen Bereichen Korrektheit zu wahren.
      Umgekehrt kann man aus einer schnellen Sprache heraus auch eine Skriptsprache aufrufen. Heute sind alle von wasm begeistert, aber Computerspiele nutzen seit etwa 20 Jahren lua für genau diesen Zweck. Spiele sind vermutlich die größte Kategorie performanceempfindlicher Software.
    • Aus demselben Grund wollte ich im Browser-Prozess Oilpan GC verwenden, aber die Browser-Leute waren damals stark dagegen, blink-Bibliotheken zu nutzen.
      Der Großteil des Chrome-UI-Codes ist zumindest als Web UI geschrieben. Heute sollte man meiner Meinung nach typescript für mehr Orchestrierungsarbeit im Browserinneren prüfen. Electron hat diese Strategie validiert.
      Allerdings scheint die aktuelle Richtung tatsächlich eher bei MiraclePtr zu liegen.
    • raw_ptr ist tatsächlich ein Smart-Pointer-Wrapper, der die meisten use-after-free-Exploits abschwächt: https://security.googleblog.com/2022/09/use-after-freedom-mi...
  • Ich habe das in eine Treemap-Visualisierung übertragen[1]: https://vrp-treemap.surge.sh/
    Die Treemap-Bibliothek wurde von evmar erstellt, einem Chrome-Urgestein, das auch in diesem Thread ist.

  • Eine sehr saubere Visualisierung. Beim Aufklappen von Bereichen verbraucht sie etwas viel CPU, aber es wäre schön, wenn das Chrome-Team intern etwas Ähnliches hätte.
    Sieht wirklich nützlich aus, um die Angriffsfläche zu verstehen.

  • Wirklich eine tolle Idee und gut umgesetzt.
    Gibt es die Rohdaten irgendwo? Sunburst oder Treemap wären ebenfalls einen Versuch wert.

  • Da das vermutlich bis auf Diff-Ebene heruntergeht, wäre es interessant, nach der Zahl der geänderten Codezeilen zu gewichten. Wenn zum Beispiel in Datei A 10 Zeilen und in Datei B 1 Zeile geändert wurden, liegt der Großteil des Bugs in Datei A, also würde Datei A 1/11 der Prämie zugewiesen?
    Oder man könnte nach geänderten Zeilen / Gesamtzeilen der Datei verteilen. Dann ließe sich mit einem Preisschild sehen, wie bugträchtig jede Datei ist.

    • Damit würde man den gewünschten Effekt erzielen. Code wie Tests ist wahrscheinlich sehr ausführlich, während die eigentliche Schwachstelle oft nur aus wenigen Zeichen besteht.
  • Es wäre schön, bei jedem Knoten auch die durchschnittliche Prämie pro Datei anzuzeigen.

  • Kleiner Einwand: DEPS, AUTHORS und BUILD.gn-Dateien sollte man besser nicht einbeziehen.

  • Wie wäre es mit einer Version, bei der die Beträge nach Codezeilen normalisiert sind?

    • Mich würde interessieren, warum du danach fragst. In Software und Security halte ich Codezeilen für eine ziemlich bedeutungslose Kennzahl.
    • Oder man könnte nach der Anzahl der Wörter normalisieren, die zu einem Bug geschrieben wurden. Das kann als Proxy für Komplexität dienen.