- Chromium Money Tree Browser associe les récompenses Chrome VRP aux historiques de modifications des répertoires et fichiers du dépôt Chromium, afin de parcourir où les récompenses de sécurité se sont accumulées dans l’arborescence du code
- Le montant des récompenses est réparti en divisant par le nombre de fichiers modifiés ; ainsi, si la correction d’un bug avec une prime de 1 000 $ modifie 5 fichiers, 200 $ sont attribués à chacun
- Les agrégats de plus haut niveau affichent root 9 873 277 $ / 10 944 cas, chromium 9 014 838 $ / 10 218 cas, chrome 2 568 260 $ / 2 574 cas
- De nombreuses zones apparaissent ventilées jusqu’au niveau fichier, comme chrome/browser/ui/views, extensions, media, safe_browsing, enterprise, Android, net, device, gpu, storage, base, iOS, pdf, etc. ; V8 représente aussi une part importante avec 858 439 $ / 726 cas
- Une note précise que les données et l’interface sont dans un état « very very hacked together », et que la couverture s’arrête au début novembre 2023 ; il vaut donc mieux voir l’outil comme une carte d’exploration que comme un document comptable exact
La manière de répartir les récompenses dans l’arborescence du code
- Il s’agit d’un navigateur qui relie les primes de bug bounty du Chrome VRP à l’arborescence des fichiers et répertoires du codebase Chromium
- Lorsqu’un correctif de sécurité modifie plusieurs fichiers, la récompense est divisée par le nombre de fichiers puis attribuée à chacun
- Ce rapprochement sert surtout à repérer « quel code est souvent modifié en même temps que des récompenses de sécurité »
- Rien qu’avec les agrégats de plus haut niveau, on voit déjà une répartition significative des récompenses sur l’ensemble de Chromium
- root : 9 873 277 $ / 10 944 cas
- chromium : 9 014 838 $ / 10 218 cas
- chrome : 2 568 260 $ / 2 574 cas
- chrome/browser : 2 250 643 $ / 1 920 cas
Répartition notable par répertoire
- Sous chrome/browser/ui/views, la distribution des récompenses est finement découpée par fonctionnalités de l’interface utilisateur
- views : 514 665 $ / 441 cas
- tabs : 56 705 $ / 30 cas
- eye_dropper : 47 000 $ / 7 cas
- bookmarks : 46 697 $ / 31 cas
- payments : 43 623 $ / 60 cas
- media_router : 36 395 $ / 12 cas
- tab_sharing : 30 591 $ / 9 cas
- Les zones liées aux extensions Chrome reviennent aussi comme de gros ensembles
- extensions : 157 507 $ / 262 cas
- extensions/api : 115 471 $ / 161 cas
- api/tabs : 42 705 $ / 48 cas
- api/debugger : 28 488 $ / 35 cas
- api/downloads : 15 225 $ / 13 cas
- Une autre zone extensions est aussi comptabilisée à 132 615 $ / 213 cas, incluant renderer, guest_view/web_view et l’API file_system
- V8 apparaît comme la plus grande zone secondaire unique dans les notes fournies
- V8 au total : 858 439 $ / 726 cas
- v8/src : 626 845 $ / 503 cas
- v8/test : 209 030 $ / 195 cas
- v8/src/compiler : 151 267 $ / 85 cas
- v8/src/heap : 91 891 $ / 64 cas
- v8/src/builtins : 68 133 $ / 30 cas
- v8/test/mjsunit : 164 644 $ / 113 cas
- Côté chrome/browser, on remarque surtout les points de contact utilisateur comme l’UI, les onglets, l’autofill, les mots de passe, DevTools ou le menu contextuel du renderer
- chrome/browser/autofill : 114 656 $ / 40 cas
- chrome/browser/tabs : 92 316 $ / 25 cas
- passwords : 51 060 $ / 10 cas
- chrome_content_browser_client.cc : 51 512 $ / 11 cas
- devtools : 48 255 $ / 35 cas
- renderer_context_menu : 47 842 $ / 16 cas
- printing : 42 225 $ / 14 cas
- payments : 41 252 $ / 10 cas
- Les domaines media, sécurité, entreprise et plateforme totalisent aussi des montants élevés
- media : 134 523 $ / 65 cas, et séparément la zone chrome/browser/media à 89 008 $ / 34 cas
- safe_browsing : 80 161 $ / 31 cas
- enterprise : 59 000 $ / 38 cas
- ash : 130 389 $ / 161 cas, avec une autre section ash à 56 867 $ / 55 cas
- mojo : 112 725 $ / 26 cas
- net : 97 558 $ / 175 cas
- device : 61 770 $ / 32 cas
- gpu : 51 155 $ / 30 cas
- storage : 48 303 $ / 66 cas
- base : 36 013 $ / 27 cas
- Android et iOS montrent aussi une répartition séparée des récompenses dans leur code plateforme
- Zones Java, ressources et tests de Android chrome/browser : 94 441 $ / 159 cas
- Chemins Android Java : 62 571 $ / 91 cas
- Android fullscreen : 18 707 $ / 11 cas, dont FullscreenHtmlApiHandler.java à 18 540 $ / 10 cas
- iOS : 33 625 $ / 86 cas
- ios/chrome/browser/web : 11 663 $ / 4 cas
- ios/chrome/browser/ui : 9 884 $ / 24 cas
Fichiers de test et précautions d’interprétation
- Les données de test et les fichiers de tests de régression sont aussi inclus dans la répartition des récompenses
- test : 147 193 $ / 311 cas
- test/data : 116 355 $ / 271 cas
- test/data/extensions/api_test : 59 337 $ / 166 cas
- V8 test/mjsunit/regress : 82 180 $ / 58 cas
- V8 test/mjsunit/compiler : 46 233 $ / 28 cas
- C’est parce que lorsqu’un correctif de sécurité est enregistré avec des modifications de fichiers de test, une part de la récompense leur est aussi attribuée
- La méthode de calcul est simple, ce qui rend difficile de lire directement ces montants comme un indicateur de risque ou comme la cause d’une vulnérabilité
- Comme la récompense est divisée par le « nombre de fichiers modifiés », le montant attribué à un fichier ne représente pas directement son niveau de risque propre
- Une note avertit que les données et l’interface sont dans un état « very very hacked together » et qu’il ne faut pas s’attendre à une excellente UX ni à des données parfaitement exactes
- La couverture des données va jusqu’au début novembre 2023
- Un lien vers une discussion connexe est également fourni
1 commentaires
Avis de Hacker News
C’est assez proche de quelque chose que je voulais faire depuis longtemps. Il me semblait utile de calculer la probabilité qu’un changement donné provoque un problème, à partir de l’historique des changements cassants survenus dans le même fichier, ou dans la même zone du fichier
En gros, il s’agirait d’attribuer un score de risque à chaque changement, d’afficher ce score pour chaque PR afin que les reviewers sachent quel code examiner avec plus d’attention, et de mettre aussi en évidence les changements risqués au moment du déploiement
La difficulté, c’est de continuer à suivre la même zone de code quand sa position monte ou descend à cause d’insertions/suppressions plus haut dans le fichier ; les algorithmes qui s’appuient simplement sur les numéros de ligne posent problème ici
Cela dit, comme dans cet exemple, même une approche limitée au niveau fichier semble déjà pouvoir être très utile
Pour les changements à haut risque, nous lançons davantage de tests, mais pas des tests unitaires : des tests clients. Parfois, il y a 100 000 tests clients possibles, donc nous les classons puis n’en exécutons qu’un petit sous-ensemble
C’est un problème difficile. Une observation intéressante est que le changement causal contient bien un ou deux symboles causaux, mais que la connectivité de ces symboles ressemble beaucoup à celle des symboles non causaux dans le même changement
De plus, le graphe d’appels modifié transitivement après le changement est assez grand, et une profondeur de 50 n’est pas rare. À part le degré de recouvrement entre les symboles affectés transitivement entre le changement et les tests, il est difficile d’en extraire beaucoup de signaux utiles
Les niveaux fichier et cible de build étaient trop grossiers ; les symboles AST fonctionnent bien
Très chouette. Il me semble toutefois qu’il manque quelques éléments. Je suis quasiment certain qu’il y en a eu au moins un dans third_party/ffmpeg
Ce genre de correctif arrive généralement d’abord en amont, ce qui peut le rendre difficile à suivre
Quand on parcourt le gros ensemble sous chrome/browser/ui, on en vient à réfléchir au nombre de use-after-free qui apparaissent dans des données où les gains de performance de la gestion manuelle de la mémoire comptent assez peu. Par exemple, [1] concerne un problème autour du cycle de vie de la boîte de dialogue « sélection de fichier »
Dans l’ensemble, il me semble qu’il vaudrait mieux toujours utiliser, pour ce type de code, des pointeurs plus intelligents mais plus lents, par défense. Le type
raw_ptr[3] mentionné dans [2] semblait aller dans ce sens ; peut-être que le crash de [2] est en réalité un cas où la défense a fonctionnéJe regrette qu’il n’y ait pas vraiment, dans le projet, de manière plus large de changer de dialecte entre « cette partie est du code critique pour les performances et relu avec soin » et « cette partie est peu sensible aux performances, avec beaucoup d’état asynchrone et donc facile à se tromper ». Je me suis parfois dit qu’il serait presque pertinent d’y mêler un autre langage avec GC pour le second cas
Pour information, j’ai travaillé sur ce code il y a longtemps, et je ne serais pas surpris d’avoir créé plus de zéro de ces bugs
[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...
unsafede RustEt ce type de code fait littéralement partie des motivations initiales qui ont donné naissance à Rust. Le langage a été conçu dès le départ avec l’implémentation de navigateurs en tête
L’inverse est également possible : appeler un langage de script depuis un langage rapide. Aujourd’hui, tout le monde s’enthousiasme pour wasm, mais les jeux vidéo utilisent déjà lua de cette manière depuis environ 20 ans. Les jeux constituent probablement la plus grande catégorie de logiciels sensibles aux performances
La majorité du code UI de Chrome est au moins écrite en Web UI. Aujourd’hui, je pense qu’il faudrait envisager TypeScript pour davantage de tâches d’orchestration internes au navigateur. C’est une stratégie validée par Electron
Cela dit, la dynamique actuelle semble plutôt être du côté de MiraclePtr
raw_ptrest en fait un wrapper de pointeur intelligent qui atténue la plupart des exploitations de use-after-free : https://security.googleblog.com/2022/09/use-after-freedom-mi...J’en ai fait une visualisation en treemap[1] : https://vrp-treemap.surge.sh/
La bibliothèque de treemap a été créée par evmar, un ancien de Chrome qui se trouve aussi dans ce fil
Visualisation très propre. Elle consomme un peu de CPU quand on déplie des zones, mais ce serait bien que l’équipe Chrome ait quelque chose de similaire en interne
Pour ainsi dire, cela semble vraiment utile pour comprendre la surface d’attaque
Idée vraiment excellente, et l’implémentation est bonne
Les données brutes sont-elles disponibles quelque part ? Un sunburst ou une treemap vaudraient aussi le coup d’être essayés
Comme cela descend probablement jusqu’au niveau du diff, ce serait intéressant de pondérer par le nombre de lignes de code modifiées. Par exemple, si 10 lignes ont changé dans le fichier A et 1 ligne dans le fichier B, la plupart du bug se trouve dans le fichier A, donc 1/11 de la prime serait attribué au fichier A ?
Ou bien on pourrait répartir selon le nombre de lignes modifiées / le nombre total de lignes du fichier. On pourrait alors voir à quel point chaque fichier est truffé de bugs, avec une étiquette de montant
Ce serait bien d’afficher aussi, pour chaque nœud, la récompense moyenne par fichier
Petite remarque, mais il vaudrait mieux ne pas inclure les fichiers DEPS, AUTHORS et BUILD.gn
Et une version normalisée par nombre de lignes de code ?