Durante décadas, C y sus descendientes inmediatos han sido los lenguajes de programación preferidos para la programación de sistemas. A principios de la década de 1970, cuando se desarrolló C, fue un importante paso adelante respecto del lenguaje ensamblador. Cincuenta años después, podemos hacerlo mejor.
La seguridad informática no estaba en la mente de la mayoría de las personas en 1970, ni durante muchos años después. La primera gran vulnerabilidad de seguridad en Internet ocurrió muchos años después, en 1988. Se le conocía como el gusano de Internet y aprovechaba un desbordamiento de búfer, donde una matriz en la memoria era indexada fuera de sus límites.
En la familia del lenguaje C, que incluye C++, las matrices no tienen controles de límites. Depende del programador garantizar que se acceda correctamente a la matriz. Por lo tanto, los errores de desbordamiento de búfer son comunes. Peor aún, es fácil provocar deliberadamente un desbordamiento del búfer y, con ello, acceder a una memoria a la que no se debería acceder.
El desbordamiento del búfer es sólo un ejemplo de inseguridad de la memoria . Otros ejemplos relacionados incluyen la aritmética de punteros y los punteros colgantes (también conocidos como errores de uso después de la liberación). Hoy en día, tenemos muchos lenguajes de programación que emplean una variedad de técnicas para garantizar que cualquier programa escrito en esos lenguajes estará libre de problemas de seguridad de memoria. La familia de lenguajes C no ofrece tal garantía; la seguridad de la memoria nunca fue un objetivo de diseño de estos lenguajes.
Aproximadamente el 70% de las vulnerabilidades de seguridad se deben a violaciones de la seguridad de la memoria. Esta afirmación está respaldada por datos abrumadores. La seguridad de la memoria tiene en cuenta:
En julio de 2022, 5/6 de las vulnerabilidades corregidas en Chrome 103.0.5060.134 eran problemas de seguridad de la memoria. Está claro que eliminar los errores de seguridad de la memoria sería de enorme ayuda. La industria sabe cómo hacerlo desde hace muchos años: utilizar lenguajes de programación seguros para la memoria. Históricamente, el problema siempre ha sido el coste asociado en términos de rendimiento. Debido a la importancia de la seguridad de la memoria, la gente ha estado trabajando en nuevas estrategias para lograrla sin los costos operativos tradicionales. Hoy sabemos cómo eliminar errores de seguridad de memoria con poco o ningún costo de tiempo de ejecución. Los lenguajes, como Rust, utilizan innovaciones en el diseño del sistema de tipos para garantizar la seguridad de la memoria sin un costoso soporte en tiempo de ejecución.
Esto nos lleva a una conclusión ineludible: dejar de escribir nuevo código de sistemas en C/C++ (o, más generalmente, en lenguajes no seguros para la memoria).
Esto no es un llamado a reescrituras masivas e indiscriminadas del código existente. Reemplazar el software existente es costoso y no está exento de riesgos. Sin embargo, la industria debe dejar de agravar el problema añadiendo más código inseguro para la memoria a las bases de código existentes. Para el código existente, priorice la reescritura de los componentes más sensibles: aquellos que son responsables de validar o consumir entradas de usuarios no confiables, aquellos que se ejecutan en un contexto privilegiado, aquellos que se ejecutan fuera de un entorno protegido, etc.
Esta postura, aunque ampliamente sostenida, todavía resulta controvertida para algunos. A continuación se presentan algunos de los argumentos más comunes a favor del statu quo y nuestras respuestas a ellos.
Ver Cuantificación de la inseguridad de la memoria y las reacciones a ella para una discusión detallada de los puntos anteriores.
A pesar de las objeciones, el impulso para los cambios necesarios está creciendo. Por ejemplo, se están realizando grandes inversiones en la Open Source Software Security Foundation (respaldada por la Fundación Linux). La seguridad de la memoria se ha debatido en EE.UU. Informes del Senado y de la NSA . Consumer Reports también trabaja para identificar los diversos incentivos que podrían acelerar este movimiento ofreciendo una serie de recomendaciones para empresas y agencias estatales.
Para resumir:
La importancia de la informática para la sociedad ha crecido enormemente en los últimos cincuenta años. El panorama de amenazas a nuestra infraestructura informática también ha cambiado radicalmente en las últimas décadas. Sin embargo, los lenguajes de programación que utilizamos para construir nuestros sistemas informáticos no han cambiado en consecuencia. La falta de seguridad de la memoria es la mayor fuente de vulnerabilidades de seguridad en el software. Esto no es exclusivo de ningún tipo específico de software, ya que en todos lados donde se usan lenguajes que no son seguros para la memoria abundan los problemas de seguridad de la memoria. Y en cifras, ninguna otra clase de vulnerabilidad se acerca.
Ahora tenemos los medios para abordar este problema creciente y es crucial que, como industria, lo hagamos. Afortunadamente, cada vez hay más conciencia de la situación, pero el problema es urgente y no hay tiempo que perder.