2 puntos por GN⁺ 2024-01-07 | 1 comentarios | Compartir por WhatsApp
  • 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

 
GN⁺ 2024-01-07
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

    • Llevo más de 2 años trabajando en esto. Hacemos análisis estático de cada cambio y también analizamos todo el monorepo todos los días, y lo procesamos a nivel de símbolo
      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
    • Hay que mirar no solo el código en sí, sino también al autor. Había alguien con quien trabajé que metía al menos un bug cada vez que abría un PR
    • Justo estoy leyendo un libro sobre ese tema: https://pragprog.com/titles/atcrime/your-code-as-a-crime-sce...
    • Estaría bueno combinar la ubicación del código, la procedencia/autoría y el análisis de flujo de datos sobre código sensible cercano. Sería algo que pondría en mi herramienta de revisión
  • 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

    • Estoy usando los comentarios que deja Git Watcher en los bugs de Monorail
  • 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 defensa
    Es 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...

    • Eso es básicamente describir la palabra clave unsafe de Rust
      Y 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
    • Es casi un ejemplo de escribir las partes sensibles al rendimiento en C o Rust y dejar el resto en Python. Por lo que he escuchado, los bindings Rust-Python son particularmente buenos y además facilitan mantener la corrección incluso en las partes de rendimiento crítico
      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
    • Por la misma razón, yo quería usar Oilpan GC en el proceso del navegador, pero en ese momento la gente del lado del navegador se oponía fuertemente a usar librerías de blink
      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_ptr es 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

    • Eso probablemente produciría el efecto deseado. El código como las pruebas suele ser muy verboso, pero la vulnerabilidad real muchas veces termina siendo unos pocos caracteres
  • 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?

    • Me da curiosidad por qué lo preguntas. En software y seguridad, me parece que las líneas de código no son una métrica muy significativa
    • O también se podría normalizar por la cantidad de palabras escritas sobre el bug. Podría servir como indicador indirecto de complejidad