Cerca del 70% de las vulnerabilidades de seguridad documentadas en software de sistemas durante la última década corresponden a errores de seguridad de memoria. Este artículo examina por qué el lenguaje C facilita la aparición de esa categoría de fallos y de qué manera Rust los previene mediante garantías que el compilador verifica antes de producir el binario. Se revisan las cifras publicadas por Microsoft y Google, el caso de adopción de Rust en el sistema operativo Android y las limitaciones que conviene reconocer para sostener una valoración rigurosa.
Una categoría de error que no cede
Conviene precisar desde el inicio el alcance de la cifra que da título a este texto. Cuando se afirma que se puede eliminar el 70% de las vulnerabilidades, la referencia no abarca la totalidad de las brechas de seguridad que existen en el mundo. La cifra describe una proporción concreta, la fracción de vulnerabilidades a las que se asigna un identificador CVE (Common Vulnerabilities and Exposures) cuyo origen está en errores de seguridad de memoria.
El Microsoft Security Response Center reportó en 2019, a partir de la revisión histórica de cada vulnerabilidad reportada en sus productos desde 2004, que alrededor del 70% de los CVE que la empresa asigna cada año corresponden a problemas de seguridad de memoria. La proporción se ha mantenido prácticamente constante, y Microsoft la reiteró en su informe de seguridad de noviembre de 2025. El proyecto Chromium de Google reporta una cifra equivalente para sus errores de seguridad graves, y el equipo Project Zero, al analizar vulnerabilidades de día cero explotadas activamente, encontró que el 67% correspondía a corrupción de memoria. La Agencia de Seguridad Nacional de Estados Unidos y la agencia CISA (Cybersecurity and Infrastructure Security Agency) retoman esta estadística en sus recomendaciones oficiales sobre lenguajes de memoria segura, lo que le da respaldo institucional además del sector corporativo.
La convergencia de fuentes independientes alrededor del mismo orden de magnitud es lo que sostiene el peso del argumento. Distintos actores, con metodologías propias y sin coordinarse entre sí, llegaron por separado a un número muy similar.

¿Qué errores comprende la seguridad de memoria?
La seguridad de memoria designa la propiedad de un programa según la cual todo acceso a memoria está bien definido. Su ausencia produce una familia de fallos conocida y bien estudiada, entre ellos el desbordamiento de búfer o buffer overflow (escritura más allá de los límites reservados para una estructura), el uso después de liberación o use after free (acceso a memoria que ya fue devuelta al sistema), el puntero colgante o dangling pointer, la doble liberación o double free y la condición de carrera o race condition sobre datos compartidos entre hilos. Todos comparten una consecuencia común, ya que derivan en comportamiento indefinido, un estado en el que el programa puede hacer cualquier cosa, desde fallar sin darnos un aviso hasta ejecutar código bajo control de un atacante.
La gravedad de estos errores está en que suelen ser la puerta de entrada para ataques más complejos. Un desbordamiento de búfer puede convertirse en ejecución remota de código, y técnicas como la programación orientada a retorno (es una técnica de hackeo que reutiliza pedacitos de código que ya están en el programa, uniéndolos como un rompecabezas para hacer que haga algo malicioso, sin tener que meter código nuevo) permiten eludir buena parte de las defensas que los sistemas operativos modernos incorporan para contenerlos.
¿Por qué el lenguaje C facilita estos fallos?
El lenguaje C le da al programador control directo sobre la memoria. Esa característica explica su permanencia durante medio siglo en sistemas operativos, controladores de dispositivos y software embebido, donde la ausencia de un recolector de basura o garbage collector y el acceso cercano al hardware resultan deseables. La contrapartida es que C deja en manos del programador la tarea de gestionar correctamente cada reserva y liberación, sin verificar durante la compilación que los accesos respeten los límites de las estructuras ni que los punteros sigan apuntando a memoria válida.
En consecuencia, un programa en C puede tener un uso después de liberación o un desbordamiento de búfer y compilar sin ninguna advertencia. El error aparece en tiempo de ejecución, muchas veces bastante después de que el código se escribió, y en los casos que importan para la seguridad, cuando un atacante lo provoca de manera deliberada. La experiencia acumulada durante décadas muestra que ningún volumen de herramientas de análisis estático o static analysis, pruebas de fuzzing, revisiones de código o capacitación ha logrado bajar de forma sustancial la proporción de estos fallos. La cifra estable del 70% refleja esa limitación.
El modelo de Rust y la verificación durante la compilación
Rust, cuyo desarrollo comenzó en 2006 en Mozilla y cuya versión 1.0 se publicó en 2015, fue pensado para ofrecer un rendimiento comparable al de C y C++ junto con garantías de seguridad de memoria que se comprueban antes de que el programa exista como tal. La idea de fondo es sencilla aunque su implementación no lo sea. Cada dato en memoria tiene un único dueño en el código, y el compilador lleva la cuenta de quién puede leerlo, quién puede modificarlo y hasta cuándo sigue siendo válido. Ese seguimiento lo hace un componente del propio compilador llamado verificador de préstamos, conocido en inglés como borrow checker, y lo hace durante la compilación, no cuando el programa ya está corriendo.
En la práctica, Rust revisa el uso de la memoria antes de generar el programa. Si el código intenta acceder a un dato que ya no es válido o realizar operaciones que podrían provocar conflictos de memoria, el compilador detiene la compilación hasta que el problema se corrija. A diferencia de C o C++, donde estos errores pueden llegar a producción, Rust bloquea durante la compilación categorías enteras de fallos como use-after-free, referencias colgantes y data races. La prevención ocurre antes de la ejecución, no después.

La evidencia empírica
El caso mejor documentado es el de Android. Google empezó a priorizar el desarrollo de código nuevo en lenguajes de memoria segura alrededor de 2019 y anunció formalmente el soporte de Rust en 2021. En septiembre de 2024 reportó que la proporción de vulnerabilidades de Android atribuibles a errores de memoria bajó del 76% en 2019 a un 24% estimado para finales de 2024, una cifra muy por debajo del promedio del 70% que se observa en la industria. En números absolutos, las vulnerabilidades de seguridad de memoria pasaron de 223 en 2019 a menos de 50 en 2024.
Un dato adicional refuerza el argumento desde la perspectiva de la ingeniería. Según Jeff Vander Stoep, del equipo de seguridad de Android, el código nuevo escrito en Rust tiene una densidad de vulnerabilidades de memoria menor que el código heredado en C y C++. Google reportó además que los cambios en Rust tienen una tasa de reversión cuatro veces menor y requieren cerca de 25% menos tiempo de revisión de código, lo que sugiere que la adopción del lenguaje mejoró la velocidad de entrega y la calidad del software además de su seguridad. Vale la pena notar que esta reducción ocurrió aun cuando el código en C y C++ sigue presente en la base de Android, lo que apunta a que el efecto viene de cómo se escribe el código nuevo y no de una reescritura masiva del código existente.
Los límites del argumento
Rust ofrece una vía de escape deliberada mediante el bloque unsafe, que habilita operaciones de bajo nivel comparables a las de C y suspende algunas de las verificaciones del compilador en la región marcada. Dentro de esos bloques, los errores de seguridad de memoria pueden volver a aparecer. Un caso concreto lo ilustra bien, ya que en 2025 se documentó la vulnerabilidad CVE-2025-48530, de severidad alta, originada en un bloque unsafe dentro de un analizador de imágenes AVIF en Android, que en combinación con otra condición podía habilitar la ejecución remota de código. El fallo se identificó y corrigió antes de su publicación, y mecanismos de protección en tiempo de ejecución limitaron su explotabilidad.
El episodio confirma que unsafe no desactiva por completo las garantías del lenguaje y que las defensas en capas siguen siendo necesarias. La lección práctica para quien adopte Rust es que el código marcado como unsafe debe mantenerse reducido, aislado y sujeto a una revisión especialmente cuidadosa, precisamente porque ahí se concentra el riesgo que el resto del lenguaje elimina.
Vale la pena señalar también que adoptar Rust implica una curva de aprendizaje real. El verificador de préstamos rechaza construcciones que un programador de C escribiría sin dificultad, y aprender bien el modelo de propiedad toma tiempo. C y C++, por su parte, conservan una base instalada enorme y un ecosistema maduro que no va a desaparecer en el corto plazo. En la práctica, pocas organizaciones están reescribiendo su código existente. Lo común es mantener ese código como está, buscar que Rust conviva bien con él, y empezar a escribir en Rust lo que se construye de aquí en adelante.
Conclusión
Los errores de seguridad de memoria representan cerca del 70% de las vulnerabilidades con CVE asignado en software de sistemas. Esa cifra viene de fuentes independientes que coinciden entre sí, no de una sola organización. Rust elimina esa categoría completa de errores en el código que respeta su modelo de propiedad, porque las verificaciones ocurren durante la compilación y no después. El caso de Android muestra que ese efecto es real y medible, no solo teórico, en un entorno de producción de gran escala.
Nada de esto significa que Rust resuelva todos los problemas de seguridad. Los bloques unsafe pueden reintroducir los mismos errores que el lenguaje previene en el resto del código, y C seguirá presente en la infraestructura existente durante mucho tiempo. Además, el 70% deja un 30% de vulnerabilidades (inyección SQL, XSS, fallas de configuración, errores de lógica de negocio, ingeniería social) que Rust no toca en absoluto, ya que esas no son problemas de memoria. Rust ataca una categoría específica y bien delimitada del problema, no la seguridad informática en general. Dentro de esa categoría, sin embargo, la evidencia es clara. La seguridad de memoria ya no depende solo de qué tan disciplinado sea cada programador, porque el lenguaje mismo puede garantizarla desde antes de que el código corra.
Referencias
Microsoft Security Response Center – A proactive approach to more secure code. Recuperado el 16 de julio de 2026.
Microsoft Security Response Center – We need a safer systems programming language. Recuperado el 16 de julio de 2026.
Windows Experience Blog (Microsoft) – Advancing security with Windows and Surface: Microsoft SFI Report Nov 2025. Recuperado el 16 de julio de 2026.
CISA – The Urgent Need for Memory Safety in Software Products. Recuperado el 15 de julio de 2026.
Google Online Security Blog – Eliminating Memory Safety Vulnerabilities at the Source. Recuperado el 15 de julio de 2026.
Google Security Blog – Rust in Android: move fast and fix things. Recuperado el 15 de julio de 2026.
The Hacker News – Rust Adoption Drives Android Memory Safety Bugs Below 20% for First Time. Recuperado el 15 de julio de 2026.
NVD (NIST) – CVE-2025-48530 Detail. Recuperado el 15 de julio de 2026.
Android Open Source Project – Android Security Bulletin, agosto de 2025. Recuperado el 8 de julio de 2026.
