- Chromium Money Tree Browser mapea las recompensas del Chrome VRP al historial de cambios por directorio y archivo del repositorio de Chromium, para poder ver de un vistazo en qué partes del árbol de código se han acumulado las recompensas de seguridad
- El monto de la recompensa se reparte según la cantidad de archivos modificados; si una corrección de bug con recompensa de $1,000 cambia 5 archivos, a cada archivo se le asignan $200
- La agregación de nivel superior muestra root $9,873,277 / 10,944 casos, chromium $9,014,838 / 10,218 casos, y chrome $2,568,260 / 2,574 casos
- Varias áreas como chrome/browser/ui/views, extensions, media, safe_browsing, enterprise, Android, net, device, gpu, storage, base, iOS y pdf aparecen desglosadas a nivel de archivo, y V8 también ocupa una porción importante con $858,439 / 726 casos
- Se advierte que los datos y la UI están en un estado de “very very hacked together”, y que el alcance llega solo hasta principios de noviembre de 2023, así que conviene verlo más como un mapa para explorar que como una contabilidad precisa
Cómo se distribuyen las recompensas sobre el árbol de código
- Es un navegador que muestra las recompensas del programa de bug bounty Chrome VRP vinculadas al árbol de archivos y directorios del código fuente de Chromium
- Si una corrección de seguridad modifica varios archivos, la recompensa se divide entre la cantidad de archivos y se asigna una parte a cada uno
- Esta relación sirve más para revisar “qué código cambió con frecuencia junto con recompensas de seguridad”
- Incluso viendo solo la agregación superior ya se aprecia una distribución considerable de recompensas en todo Chromium
- root: $9,873,277 / 10,944 casos
- chromium: $9,014,838 / 10,218 casos
- chrome: $2,568,260 / 2,574 casos
- chrome/browser: $2,250,643 / 1,920 casos
Distribución destacada por directorio
- Debajo de chrome/browser/ui/views, la distribución de recompensas está desglosada con bastante detalle por funciones de la UI de usuario
- views: $514,665 / 441 casos
- tabs: $56,705 / 30 casos
- eye_dropper: $47,000 / 7 casos
- bookmarks: $46,697 / 31 casos
- payments: $43,623 / 60 casos
- media_router: $36,395 / 12 casos
- tab_sharing: $30,591 / 9 casos
- Las áreas relacionadas con Chrome extensions también aparecen repetidamente como bloques grandes
- extensions: $157,507 / 262 casos
- extensions/api: $115,471 / 161 casos
- api/tabs: $42,705 / 48 casos
- api/debugger: $28,488 / 35 casos
- api/downloads: $15,225 / 13 casos
- Otra área separada de extensions también se contabiliza con $132,615 / 213 casos, e incluye renderer, guest_view/web_view y la API de file_system
- V8 parece ser la subárea individual más grande en las notas proporcionadas
- V8 total: $858,439 / 726 casos
- v8/src: $626,845 / 503 casos
- v8/test: $209,030 / 195 casos
- v8/src/compiler: $151,267 / 85 casos
- v8/src/heap: $91,891 / 64 casos
- v8/src/builtins: $68,133 / 30 casos
- v8/test/mjsunit: $164,644 / 113 casos
- Del lado de chrome/browser, destacan puntos de contacto con el usuario como UI, pestañas, autocompletado, contraseñas, DevTools y renderer context menu
- chrome/browser/autofill: $114,656 / 40 casos
- chrome/browser/tabs: $92,316 / 25 casos
- passwords: $51,060 / 10 casos
- chrome_content_browser_client.cc: $51,512 / 11 casos
- devtools: $48,255 / 35 casos
- renderer_context_menu: $47,842 / 16 casos
- printing: $42,225 / 14 casos
- payments: $41,252 / 10 casos
- Las áreas de medios, seguridad, enterprise y plataformas también acumulan montos altos
- media: $134,523 / 65 casos, y el área separada chrome/browser/media tiene $89,008 / 34 casos
- safe_browsing: $80,161 / 31 casos
- enterprise: $59,000 / 38 casos
- ash: $130,389 / 161 casos, y otra sección separada de ash continúa con $56,867 / 55 casos
- mojo: $112,725 / 26 casos
- net: $97,558 / 175 casos
- device: $61,770 / 32 casos
- gpu: $51,155 / 30 casos
- storage: $48,303 / 66 casos
- base: $36,013 / 27 casos
- Android e iOS también muestran una distribución separada de recompensas en código específico de plataforma
- Áreas Java, recursos y pruebas de Android chrome/browser: $94,441 / 159 casos
- Ruta Android Java: $62,571 / 91 casos
- Android fullscreen: $18,707 / 11 casos, y FullscreenHtmlApiHandler.java tiene $18,540 / 10 casos
- iOS: $33,625 / 86 casos
- ios/chrome/browser/web: $11,663 / 4 casos
- ios/chrome/browser/ui: $9,884 / 24 casos
Archivos de prueba y advertencias de interpretación
- Los datos de prueba y los archivos de pruebas de regresión también están incluidos en la distribución de recompensas
- test: $147,193 / 311 casos
- test/data: $116,355 / 271 casos
- test/data/extensions/api_test: $59,337 / 166 casos
- V8 test/mjsunit/regress: $82,180 / 58 casos
- V8 test/mjsunit/compiler: $46,233 / 28 casos
- Esto se debe a que, cuando una corrección de seguridad se registra junto con cambios en archivos de prueba, parte de la recompensa también se distribuye a esos archivos
- Como el método de cálculo es simple, no es fácil leer esos montos directamente como nivel de riesgo o causa de vulnerabilidad
- Como la recompensa se divide entre la “cantidad de archivos modificados”, el monto de un archivo no significa directamente el riesgo de ese archivo en sí
- Los datos y la UI están en un estado de “very very hacked together”, y se advierte que no se debe esperar una gran UX ni datos perfectamente precisos
- El rango de datos llega hasta principios de noviembre de 2023
- También se proporciona un enlace a la discusión relacionada
1 comentarios
Comentarios en Hacker News
Es bastante parecido a algo que quería hacer desde hace tiempo. Pensaba que sería útil calcular la probabilidad de que cierto cambio cause problemas basándose en el historial de cambios destructivos ocurridos antes en el mismo archivo o en la misma zona dentro del archivo
Básicamente, asignar una puntuación de riesgo a cada cambio y mostrar esa puntuación en cada PR para que el revisor sepa qué código mirar con más cuidado, y también resaltar los cambios riesgosos al momento del despliegue
La parte difícil es seguir rastreando la misma región de código cuando su posición sube o baja por inserciones/eliminaciones arriba; los algoritmos que dependen solo del número de línea fallan ahí
Aun así, parece que incluso hacerlo solo a nivel de archivo podría ser lo bastante útil
A los cambios con mayor riesgo les corremos más pruebas, pero no pruebas unitarias sino pruebas de cliente. A veces hay 100 mil pruebas de cliente posibles, así que las priorizamos y ejecutamos solo un subconjunto pequeño
Es un problema difícil. Una observación interesante es que dentro del cambio causal sí hay uno o dos símbolos causales, pero la conectividad de esos símbolos es muy parecida a la de los símbolos no causales dentro del mismo cambio
Además, el grafo de llamadas modificado transitivamente después del cambio es bastante grande, y una profundidad de 50 no es nada rara. Fuera del grado de solapamiento entre símbolos transitivamente afectados entre el cambio y las pruebas, ha sido difícil extraer muchas señales útiles
El nivel de archivo y el nivel de objetivo de build eran demasiado gruesos, y los símbolos del AST están funcionando bien
Está muy bueno. Pero parece que faltan algunos elementos. Estoy seguro de que había al menos uno en third_party/ffmpeg
Ese tipo de correcciones normalmente primero entran upstream, así que puede ser difícil rastrearlas
Si uno recorre el gran conjunto bajo chrome/browser/ui, se pone a pensar cuántos use-after-free aparecen en datos donde la ventaja de rendimiento de manejar memoria manualmente no importa tanto. Por ejemplo, [1] es un problema alrededor del ciclo de vida del diálogo de “seleccionar archivo”
Viéndolo en grande, parece mejor usar siempre punteros más inteligentes pero más lentos como defensa en este tipo de código. En [2], el tipo
raw_ptr[3] parecía intentar ayudar con eso, y quizá el crash de [2] en realidad sí fue un caso exitoso de defensaEs una pena que no haya una buena forma dentro del proyecto de cambiar de dialecto de manera más amplia entre “esta parte es código crítico para el rendimiento y revisado con mucho cuidado” y “esta parte es menos sensible al rendimiento y tiene mucho estado asíncrono, así que es fácil equivocarse”. Incluso he pensado que casi valdría la pena mezclar un lenguaje aparte con GC para lo segundo
Como referencia, trabajé en este código hace mucho tiempo, y no me sorprendería si yo hubiera creado más de 0 de estos 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 RustY este tipo de código fue literalmente una de las motivaciones originales por las que Rust nació. De hecho, fue un lenguaje diseñado pensando en implementar navegadores
También se puede hacer al revés, llamando un lenguaje de scripting desde un lenguaje rápido. Hoy todo el mundo se entusiasma con wasm, pero los juegos de computadora ya llevan como 20 años usando lua para algo así. Los juegos probablemente sean la categoría más grande de software sensible al rendimiento
La mayor parte del código de UI de Chrome ya está escrita al menos como Web UI. Hoy en día, creo que habría que considerar typescript para más trabajo de orquestación dentro del navegador. Es una estrategia que Electron ya validó
Dicho eso, parece que la dirección actual sí va más por el lado de MiraclePtr
raw_ptres en realidad un wrapper de smart pointer que mitiga la mayoría de las explotaciones de use-after-free: https://security.googleblog.com/2022/09/use-after-freedom-mi...Pasé esto a una visualización tipo treemap[1]: https://vrp-treemap.surge.sh/
La librería de treemap la hizo evmar, un veterano de Chrome que también aparece en este hilo
Visualización muy limpia. Al expandir áreas sí usa un poco bastante de CPU, pero estaría bueno que el equipo de Chrome tuviera algo parecido internamente
Para entender la superficie de ataque, de verdad se ve muy útil
Es una idea realmente genial y está bien implementada
¿Los datos en bruto están en algún lado? También valdría la pena probar con un sunburst o un treemap
Como esto probablemente ya bajó hasta el nivel de diff, sería interesante ponderarlo por cantidad de líneas de código modificadas. Por ejemplo, si se cambiaron 10 líneas en el archivo A y 1 línea en el archivo B, entonces la mayor parte del bug está en el archivo A, así que ¿se le asignaría 1/11 de la recompensa al archivo A?
O también se podría repartir según líneas modificadas / líneas totales del archivo. Así podrías ver qué tan bugueado está cada archivo junto con una etiqueta de monto
También estaría bueno mostrar el promedio de recompensa por archivo en cada nodo
Un detalle menor, pero quizá convenga excluir los archivos DEPS, AUTHORS y BUILD.gn
¿Qué tal una versión con el monto normalizado por líneas de código?