- 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
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.
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.
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.
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...
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.
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.
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_ptrist 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.
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?