En noviembre de 2022, la Agencia de Seguridad Nacional de EE. UU. lanzó un informe sobre la seguridad en la gestión de la memoria RAM. Si miras otros informes de la NSA sobre el tema, notarás que se centran en el cifrado de datos o la protección del ciclo de producción y demás problemas de organización, por lo que dirigirse directamente a los desarrolladores de software es un movimiento inusual para la agencia. Esto podría dar a pensar que se trata de algo particularmente importante. Básicamente, la NSA incita a los desarrolladores de software a cambiar a lenguajes de programación cuya arquitectura implique mayor seguridad al momento de trabajar con la memoria; y dejar de usar C y C++. De no hacerlo, se recomienda implementar un conjunto de medidas para probar el software para buscar de vulnerabilidades y evitar su explotación.
Esto es algo bastante obvio para los programadores, por lo que la llamada de la NSA no va enfocada a ellos de forma directa, sino a la gerencia o representantes comerciales. La redacción, en realidad, está claramente centrada en las empresas. Ahora intentaremos analizar los argumentos presentados sin ser demasiado técnicos.
La seguridad de la memoria
Abramos nuestro último Informe sobre la evolución de las amenazas en el tercer trimestre de 2022 y veamos las vulnerabilidades más usadas durante los ciberataques. En primer lugar, sigue estando la vulnerabilidad CVE-2018-0802 en el componente Editor de ecuaciones del paquete Microsoft Office, descubierta en el 2018. Un procesamiento de datos incorrecto en la RAM, culmina en la apertura de un documento malicioso de Microsoft Word que podría llevar al lanzamiento de código arbitrario. Otra vulnerabilidad popular entre los delincuentes es la CVE-2022-2294 en el componente WebRTC del navegador Google Chrome que lleva a la ejecución de código arbitrario como resultado de un error de desbordamiento de búfer. Otra vulnerabilidad, la CVE-2022-2624, encontrada en la herramienta de visualización de PDF de Chrome, puede provocar también un desbordamiento de búfer.
Claro que no todas las vulnerabilidades de software se producen debido una gestión insegura de la RAM, pero muchas de ellas sí. El informe de la NSA cita las estadísticas de Microsoft de que el 70 % de las vulnerabilidades descubiertas son causadas por los errores en la gestión de la memoria.
¿Por qué pasa esto? Si el problema de las filtraciones de memoria es tan grave, ¿por qué no podemos unirnos de alguna manera para ya no escribir código vulnerable? La raíz del problema es el uso de los lenguajes de programación C y C++. Su arquitectura brinda a los desarrolladores mucha libertad para trabajar con la RAM. Pero la responsabilidad viene junto con la libertad. Los programadores de C/C++ tienen que implementar mecanismos para escribir y leer datos de forma segura. A su vez, los lenguajes de programación de alto nivel como C#, Rust, Go y otros se encargan de eso. El tema es que al compilar el código fuente del programa, los medios de gestión segura de la memoria se introducen de forma automática, y los desarrolladores no necesitan dedicar su tiempo a eso. Rust utiliza todavía más medios para mejorar la seguridad, hasta restringir la compilación de código potencialmente peligroso al tiempo que muestra al programador el error.
Claro que dejar de usar C/C++ no es factible mientras estos lenguajes sigan siendo indispensables para algunas tareas, como cuando se necesita código para el MCU u otros dispositivos con serias limitaciones en el poder de cómputo y el tamaño de la memoria. En condiciones equilibradas, los lenguajes de programación de alto nivel pueden conducir a la creación de programas que requieren más recursos. Pero las estadísticas de amenazas comunes nos muestran que los ataques se dirigen más frecuentemente al software de usuarios domésticos (como navegadores y editores de texto), que se ejecutan en computadoras muy potentes (en comparación con los MCU, por supuesto).
No se puede solo cambiar el lenguaje de programación
Y la NSA lo sabe. No puede trasladarse una gran base de datos de software escrita en lenguajes de programación “inseguros” a otro de la noche a la mañana. Aunque hablemos de escribir un producto de software desde cero, puede haber un equipo establecido, una infraestructura y métodos de desarrollo en torno a un lenguaje de programación en particular.
Por ejemplo, imagina que te piden que te mudes de tu casa solo porque la construyeron hace mucho tiempo. Sabes que la estructura está perfectamente y que solo se derrumbaría si hay un gran terremoto y, además, ya estás acostumbrado a vivir allí. El equipo de desarrolladores de Google Chrome tiene una publicación en la que establece explícitamente que en este momento no pueden cambiar a otro lenguaje de programación (en este caso, Rust) en el que la seguridad esté integrada en la arquitectura. Quizá sea posible en un futuro, pero ahora mismo necesitan otras soluciones.
Esta misma publicación de los desarrolladores de Google Chrome también explica por qué no se puede cambiar la seguridad del código C/C++ de manera fundamental. Estos lenguajes de programación simplemente no fueron diseñados para resolver de tajo todos los problemas de compilación. Por esto, el informe de la NSA menciona dos conjuntos de medidas alternativas:
- La prueba de código para vulnerabilidades potenciales con técnicas de análisis dinámico y estático.
- Usar características que eviten la explotación de un error de código, aunque ya exista.
Los desafíos del cambio
En general, los expertos comparten la opinión de la NSA, pero pueden tener diferentes puntos sobre cómo cambiar a lenguajes de programación de alto nivel en los casos en que la necesidad surja, entre otras cosas, de los requisitos de seguridad. Primero, es importante entender que, si llega a pasar tal movimiento, tardará muchos años. Segundo, una evolución como esta tiene un precio que no todas las empresas están dispuestas a pagar. El problema de la gestión insegura de la memoria en los lenguajes de programación con un bajo nivel de abstracción es un problema sistémico. Es necesaria una solución radical, pero no esperes que mañana mismo todos comiencen a desarrollar en C#, Go, Java, Ruby, Rust o Swift. Esta situación presenta las mismas complicaciones que si se intentara obligar a toda una ciudad o país a volverse vegetarianos o cualquier otro cambio extremo de un día para otro.
Por último, el problema de la gestión insegura de la memoria puede ser muy importante, pero está lejos de ser el único problema relacionado con la seguridad del software. En las varias décadas de existencia de la industria TI, no ha sido posible crear un sistema universal y totalmente seguro para todas las tareas (exceptuando soluciones muy especializadas). Desde un punto de vista empresarial, tiene sentido tanto invertir en nuevas tecnologías (desarrollando las habilidades correspondientes y contratando especialistas con experiencia) como en la máxima protección de las tecnologías existentes. Para el desarrollo de software, podemos hablar de nuevos lenguajes de programación y tecnologías para probar el código que ya existe. Para cualquier otro negocio, puede ser invertir en nuevas tecnologías para protegerse ante ciberataques, así como probar la solidez de la infraestructura existente de manera constante. En otras palabras, una estrategia integral de la seguridad es lo óptimo y lo será por mucho tiempo.