Mejorando el manejo de vulnerabilidades web con automatización

Elihu A. Cruz
Lyft Engineering en Español
7 min readApr 24, 2023

--

Este artículo fue publicado originalmente el 20 de enero de 2022 por Nicolas Flacco en eng.lyft.com y fue traducido por Elihu A. Cruz.

Introducción

El manejo de vulnerabilidades es importante, pero puede consumir bastante tiempo. Tenemos que escanear nuestros sistemas y luego corregir las vulnerabilidades que descubrimos. En una gran organización de software esto se vuelve más desafiante — los propietarios de los servicios son responsables de arreglar las vulnerabilidades en sus sistemas junto a todas sus otras responsabilidades, además el equipo de seguridad tiene que registrar este trabajo, motivar a los ingenieros para arreglar realmente las cosas y reportar a CISO (chief information security officer (Jefe de seguridad informática))/Compliance (Cumplimiento)/etc. Afortunadamente gran parte de este trabajo se presta a ser automatizado, permitiendo a los ingenieros de seguridad enfocarse en entender y arreglar vulnerabilidades. En este artículo nos enfocaremos específicamente en vulnerabilidades web, y algunos de los divertidos retos de automatización que este proceso plantea.

Los viejos métodos no son lo mejor

Hasta hace poco, debido a nuestro cambiante entorno y consideraciones de infraestructura, el proceso de vulnerabilidades web de Lyft era un proceso muy manual, desde escanear y tabular los resultados hasta eliminar incidentes redundantes. Además, era necesario preparar manualmente reportes cada día. Todo este trabajo representaba una labor significativa (3 meses al año), y reducía el tiempo disponible para análisis de vulnerabilidades.

Nuestros miembros de ingeniería realizaban los siguientes pasos de forma manual cada mes, además del antes mencionado reporte:

  • Ejecutar el escaneo en sus computadoras usando Burp (a través de la interfaz de usuario) en una lista de enlaces, y posteriormente exportar los resultados en un documento XML. Los escaneos podían tomar varios días, y usualmente se detenían debido a errores.
  • Ejecutar un script en el documento XML para transformarlo a un archivo CSV con los incidentes para ser procesados por Jira.
  • Importar el archivo CSV a Jira para crear nuevos incidentes. Estos eran comparados con los existentes y cerrados si eran duplicados. Los incidentes se clasificaban según su gravedad, para subir o bajar su prioridad. Finalmente los incidentes eran asignados a los propietarios de los servicios.

Mejorando nuestra calidad de vida mediante la automatización

Experiencia de usuario

Idealmente, el único paso donde la intervención humana es requerida es la clasificación y asignación de los incidentes a los propietarios de los servicios. Ejecutar escaneos, convertir los resultados a incidentes de Jira y eliminar los duplicados debería ser completamente automatizado. El reporte también debería ser automatizado, dado que toda la información sobre vulnerabilidades está en Jira, y el reporte siempre tiene el mismo formato. También nos gustaría ejecutar cada uno de estos pasos independientemente. El escaneo debería ser capaz de ejecutarse cuando sea sin afectar la “jirificación” o el reporte trimestral. Un posible problema es que los estatus de los tickets en Jira pueden ser cambiados por los usuarios finales como resueltos, lo cual puede generar reportes incorrectos. Esto se soluciona ejecutando el escaneo frecuentemente y reabriendo los incidentes cuando se encuentran aún activos. Más problemático es marcar los incidentes como: ”no reparar”, lo cual causaría que el escáner los ignore en el futuro. A su vez, esto se soluciona ejecutando una inspección manual diaria de incidentes marcados como “no reparar”.

Arquitectura

Desde una perspectiva funcional, tenemos que separar tres requerimientos. Primero, necesitamos escanear uno o varios enlaces y generar un reporte XML. Segundo, necesitamos consumir el archivo XML y generar los incidentes de Jira para nuevas vulnerabilidades. Tercero, necesitamos generar un reporte trimestral y subirlo a nuestro repositorio de documentos. Cada uno de estos pasos puede ser visto como un flujo de trabajo (workflow) donde consumimos la información producida por el flujo de trabajo anterior:

Los escaneos serán frecuentes, esto significa que usaremos ya sea un ETL o un cron job. Sin embargo, debido a que estos pueden tomar varios días, tenemos que descartar los ETL, ya que la infraestructura de Lyft prefiere tiempos de ejecución más cortos para tareas individuales. Consumir el resultado del escaneo y realizar llamadas a la API de Jira parece ser una mejor alternativa para un ETL, así como la generación de reportes. Ambas tareas deberían ejecutarse relativamente rápido, y podemos tomar ventaja de la infraestructura de datos y herramientas de Lyft para un desarrollo y prototipado rápido. Un problema con el que nos encontramos inmediatamente es que necesitamos pasar los resultados del escaneo al ETL. El cron job no puede solo guardar la información en el data warehouse como nuestro ETL, así que necesitamos almacenar nuestros descubrimientos en S3, para que el ETL solicite los últimos resultados.

Otra consideración es la duplicación. El antiguo proceso manual confiaba en primero crear los incidentes en Jira, y luego marcarlos como duplicados. Esto nos pareció innecesario; antes de crear nuevos incidentes en Jira, podemos buscar incidentes existentes para ese tipo de vulnerabilidad y URL y, si existe, tenemos un duplicado y no necesitamos crear un nuevo incidente. Esto es bueno porque reduce el número de incidentes en Jira; podemos decir simplemente que vimos un incidente existente y aún no está arreglado (o ha sido marcado como “no reparar”).

Después, decidimos hacer escaneos más atómicos, es decir, escanear una sola URL y generar incidentes en Jira para esa URL. Esto facilita agregar incrementalmente nuevas URL al sistema. Es posible que queramos agendar primero los escaneos, pero no activar la creación de incidentes de Jira (o solo encenderlo en ”staging”).

Finalmente, dado que todas las vulnerabilidades web son monitoreadas en Jira, podemos obtener toda la información necesaria para nuestro reporte con una sola solicitud a Jira. Dado que diferentes niveles de gravedad tienen diferentes SLAs (Service Level Agreement), y que sabemos cuando un incidente fue creado originalmente, es trivial calcular incidencias atrasadas.

Implementación

Desde el punto de vista de la implementación, construimos la mayor parte del sistema sobre Flyte, la plataforma de procesamiento de datos y orquestación de aprendizaje automático (ML). En Lyft, Flyte era la plataforma preferida (sobre Airflow) por varias razones [1], desde las herramientas hasta el soporte para Kubernetes. Gran parte del desarrollo fue hecho con Jupyter notebooks alojados en Lyftlearn, nuestra plataforma de entrenamiento para modelos de ML, la cual permitió probar y prototipar rápidamente.

Burp normalmente se ejecuta por medio de la interfaz de usuario, pero también soporta un modelo “headless”, el cual puede mejorarse escribiendo nuestros propios plugins. Además, Burp está configurado por medio de varios archivos. Lo que realmente queremos es ejecutar el escaneo de Burp como un comando de CLI con un URL como argumento. Esto se logró escribiendo un plugin y algunos scripts como interfaces.

El reporte trimestral en Excel es generado utilizando la excelente librería de Python Xlsxwriter. Esto dió preciso control al construir la hoja de Excel celda por celda, debido a que tenemos un formato estricto. Cabe destacar que puedes escribir dataframes de Pandas directamente a un archivo de Excel, pero esto da menos control sobre el formato.

Una crítica importante que se puede hacer a este sistema es el uso de Jira como nuestra base de datos de vulnerabilidades. Jira es fantástico para la gestión de incidencias, pero cuando uno empieza a hacer cosas con Jira para las que no está diseñado, como un alto número de consultas, o el seguimiento de múltiples versiones de vulnerabilidades, o integraciones personalizadas con nuestra infraestructura, no funcionará tan bien como un almacén de datos (datastore) de uso general como Dynamo. Actualmente, toda nuestra gestión de tareas se realiza en Jira, asignando propietarios, comentando los tickets, etc., por lo que un cierto nivel de integración con Jira es necesario. En última instancia, debido al tiempo limitado y recursos de desarrollo, esta era la forma más rápida de conseguir una mejor experiencia. Sin embargo, a medio plazo es probable que pasemos a utilizar una base de datos intermedia para almacenar las vulnerabilidades.

Comentarios

Y así de fácil, nuestrxs ingenierxs ya no están ocupados con trabajo trivial, y pueden centrar su energía en comprender las vulnerabilidades e impulsar su resolución. Según nuestra cifra anterior, ¡nuestrxs ingenierxs disponen ahora de 3 meses más al año!

No podemos enfatizar lo suficiente la necesidad de construir buenas herramientas, pero las herramientas también deben ser fáciles de entender y mantener. Incluso si no se dispone de una infraestructura de datos como Lyftlearn y Flyte para construir sobre estas, los principios son los mismos: dividir el problema en partes manejables y resolver cada una de ellas de forma independiente. El sistema fue trivial de construir; sin incluir el esfuerzo para poner a funcionar a Burp como herramienta CLI, todo fue construido en una semana de tiempo de ingeniería.

Este sistema también es fácil de utilizar. Cada uno de los tres flujos de trabajo es independiente y pueden ejecutarse cuando es necesario. El escáner puede hacer lo que quiera; al flujo de Jira no le importa. Mientras pueda encontrar los resultados del escaneo en S3, funciona. Del mismo modo, el generador de informes funciona siempre y cuando tenga acceso a Jira. ¿Compliance quiere un informe ahora mismo? Fantástico, ¡podemos activar el ETL!

¡El equipo de seguridad en Lyft está contratando! Únete a nosotros para desarrollar soluciones seguras a problemas complejos.

Referencias

Si deseas aprender más acerca de seguridad e infraestructura de datos en Lyft y herramientas de terceros que usamos, consulta los siguientes enlaces (en inglés):

[1] Flyte era la plataforma preferida durante la escritura del artículo.

--

--