Una vulnerabilidad y sus consecuencias tras 22 años en SQLite

Una falla interesante en uno de los DBMS embebidos más populares.

En octubre pasado, los investigadores de Trail of Bits publicaron un detallado análisis sobre una vulnerabilidad en SQLite DBMS. En este mencionaban los posibles ataques que podrían haberse producido mediante la CVE-2022-35737, cuyas consecuencias van desde la simple caída de una aplicación hasta la ejecución de código arbitrario. Este error, que es bastante trivial en el código SQLite, resulta interesante y potencialmente peligroso por dos razones. La primera, lleva en SQLite desde octubre del 2000, es decir, prácticamente desde el principio del desarrollo de este software de código abierto y, segunda, las funciones de SQLite posibilitan el ataque a una gran variedad de programas que trabajan con dicho sistema.

Las funcionalidades de SQLite

SQLite es un sistema de gestión de bases de datos (DBMS) compacto, de código abierto y embebido que fue lanzado hace 22 años (en agosto del 2000). De esta definición, el concepto “embebido” es la clave. O O sea, SQLite no se instala como un software independiente, sino que los desarrolladores de software que tienen que trabajar con bases de datos la utilizan como una biblioteca. Por ejemplo, SQLite viene de manera 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 se volvió popular gracias a licencia abierta, su confianza y su… seguridad: aunque ya se descubrieron varios errores graves en el código de este DBMS.

La CVE-2022-35737 a detalle

Unos expertos han detectado un fallo en el código de la función sqlite3_snprintf, que se utiliza 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 utiliza toda una variable completa para calcular el tamaño de la cadena. Si dicha cadena de caracteres es muy grande, la variable puede tomar un valor negativo, lo 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 este fallo se introdujera hace 22 años en el código, cuando no era común pasar gigabytes de parámetros de función debido a las limitaciones de recursos de la época. Pero este ya no es el caso. Otro punto interesante del informe de Trail of Bits es una suposición acerca de por qué se ignoró dicho fallo durante la prueba de código estándar. El objetivo principal del procedimiento de prueba es 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. Detectar tales vulnerabilidades con la técnica fuzzing, que alimenta parámetros aleatorios como entradas de funciones, es muy complicado, ya que los métodos comunes de fuzzing no implican la generación de cadenas tan pesadas. La conclusión de los autores de la investigación es que esta técnica no puede reemplazar el análisis de código estático por completo, 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 meramente teórico contra el propio SQLite. No obstante, como ya dijimos, 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.

La verdad es que en la investigación hay bastantes suposiciones y todavía no se ha probado la posibilidad de explotar esta vulnerabilidad. Además, existe otras limitantes. De acuerdo con los datos de los desarrolladores de SQLite, la falla solo importa 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 fue compilado mediante 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 efecto de este parche ha sido poco. Probablemente, los desarrolladores de software que usan SQLite como parte de su propio código tengan que actualizar y distribuir una nueva versión del software. Hasta ese momento, la vulnerabilidad seguirá ahí. Por no hablar de los muchos programas con SQLite que dejaron de actualizarse.

Aún 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 error se añade a la colección de defectos de larga duración que perturbar la tranquilidad de los desarrolladores de software.

Consejos