El pasado octubre, los investigadores de Trail of Bits publicaron un análisis detallado sobre una vulnerabilidad en SQLite DBMS. Este artículo mencionaba los posibles ataques que podrían haberse producido mediante la CVE-2022-35737, cuyas consecuencias abarcaban desde la simple caída de una aplicación hasta la ejecución de código arbitrario. Este fallo bastante trivial en el código SQLite resulta interesante y potencialmente peligroso por dos razones. En primer lugar, lleva en SQLite desde octubre del 2000, es decir, prácticamente desde el principio del desarrollo de este software de código abierto y, en segundo lugar, las funciones de SQLite permiten el ataque a una gran variedad de programas que trabajan con este sistema.
Las funciones de SQLite
SQLite es un sistema de gestión de bases de datos (DBMS) compacto, de código abierto y embebido que se lanzó hace 22 años (en agosto del 2000). De esta definición, el concepto “embebido” es la clave. Es decir, SQLite no se instala como un software independiente, sino que se usa como una biblioteca para los desarrolladores de software que tienen que trabajar con bases de datos. Por ejemplo, SQLite está integrado de forma predeterminada en los navegadores Google Chrome, Firefox y Safari, Android, las aplicaciones de red y muchos paquetes de lanzamiento de sistemas operativos basados en el kernel de Linux. SQLite adquirió su popularidad dada su licencia abierta, su confianza y su… seguridad: aunque ya se han encontrado unos cuantos fallos graves en el código de este DBMS.
La CVE-2022-35737 en detalle
Unos expertos han detectado un fallo en el código de la función sqlite3_snprintf, que se usa para interactuar con la base de datos en programas escritos en C/C++. Si pasas una entrada con una cadena de caracteres muy grande (más de 2 GB) a esa función, el programa se bloqueará, permitiendo un ataque de denegación de servicio (DoS). En el código sqlite3_snprintf, se ha usado una variable completa para calcular el tamaño de la cadena. Si la cadena de caracteres es demasiado grande, la variable puede tomar un valor negativo, esto hace que se asigne un búfer de memoria demasiado pequeño para escribir la cadena recibida, generando un fallo de desbordamiento de búfer común.
Lo más probable es que el fallo se introdujera en el código hace 22 años, cuando no era común pasar gigabytes de parámetros de función debido a las limitaciones de recursos de la época. Pero ya no es el caso. Otro punto de interés en el informe de Trail of Bits es una suposición acerca de por qué se pasó por alto dicho fallo durante la prueba de código estándar. El procedimiento de prueba tiene como objetivo principal comprobar el código recién añadido o modificado, pero aquí el código no se ha cambiado en más de dos décadas. Es bastante difícil detectar tales vulnerabilidades con la técnica fuzzing, que alimenta parámetros aleatorios como entradas de funciones, ya que los métodos comunes de fuzzing no implican la generación de cadenas tan pesadas. Los autores de la investigación concluyen que esta técnica no puede reemplazar por completo el análisis de código estático, incluido el manual.
Unas conclusiones algo difusas
Trail of Bits pudo “modernizar” el ataque DoS original para ejecutar código arbitrario manipulando minuciosamente el contenido y el tamaño del parámetro pasado. Aunque los autores del artículo han mostrado una prueba de concepto funcional con ejemplos de ataques, se trata de un ejercicio puramente teórico contra el propio SQLite. Sin embargo, como ya hemos mencionado anteriormente, SQLite es un DBMS embebido, por lo que, para causar daños reales, alguien debería atacar una aplicación con código SQLite embebido.
Lo cierto es que hay bastantes suposiciones en la investigación y aún no se ha probado la posibilidad de explotar la vulnerabilidad. Además, hay otras limitaciones. Según los datos de los desarrolladores de SQLite, el fallo solo es relevante para la interfaz de las aplicaciones C, y solo si el código se compila con ciertos parámetros. Los propios investigadores de Trail of Bits señalan la imposibilidad de un ataque si SQLite se ha compilado utilizando una cookie de seguridad (stack canaries en inglés), un método adicional de protección contra ataques de desbordamiento de búfer que evita la ejecución de código arbitrario incluso cuando el desbordamiento es posible.
La vulnerabilidad se cerró con SQLite 3.39.2, lanzado en julio del 2022. Sin embargo, el parche ha tenido poco efecto. Los desarrolladores de software que utilizan SQLite como parte de su propio código probablemente tengan que actualizar y distribuir una nueva versión del software. Hasta entonces, la vulnerabilidad seguirá ahí. Por no hablar de los muchos programas con SQLite que han dejado de actualizarse.
Todavía no queda claro el nivel de peligrosidad de esta vulnerabilidad o si se puede explotar en la práctica. A juzgar por la definición de los desarrolladores de SQLite, la posibilidad de un ataque real es remota, pero no nula. Mientras tanto, este fallo se añade a la colección de defectos de larga duración que perturba la tranquilidad de los desarrolladores de software.