Seguridad de aplicaciones C++: top 10 vulnerabilidades para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué es crítica la seguridad del código C++?

C++ es uno de los lenguajes más potentes y de alto rendimiento, pero su flexibilidad requiere un alto grado de responsabilidad por parte del desarrollador. A diferencia de muchos lenguajes modernos con gestión automática de memoria (Java, Python), C++ proporciona acceso directo a la memoria y los recursos del sistema. Esto abre amplias oportunidades para ataques: desde desbordamiento de búfer hasta fugas de datos.

Para los desarrolladores principiantes de C++, comprender las vulnerabilidades típicas no es solo teoría, sino una necesidad. Un error de pocas líneas puede provocar la caída del servidor, la filtración de contraseñas o la ejecución de código arbitrario por parte de un atacante. En este artículo, analizaremos las 10 vulnerabilidades más comunes de C++ con ejemplos y métodos de protección.



Top 10 Vulnerabilidades de C++ con Ejemplos y Protección



1. Desbordamiento de Búfer

Problema: Escribir datos más allá de los límites de un array asignado. Este es un problema clásico de C/C++ que permite sobrescribir variables adyacentes, la dirección de retorno de la función o datos del heap.

// Ejemplo de vulnerabilidad#include <cstring>#include <iostream>

void vulnerable() { char buffer[10]; std::cout << "Ingrese una cadena: "; std::cin >> buffer; // ¡Peligro! Sin verificación de longitud}

int main() { vulnerable(); return 0;}

Consecuencias: Ejecución de código arbitrario (RCE), caída del programa.

Protección: Usar std::string, std::vector, funciones seguras (ej., strncpy con especificación de tamaño).

// Variante segura#include <string>#include <iostream>

void segura() { std::string entrada; std::getline(std::cin, entrada); std::cout << "Ingresaste: " << entrada << std::endl;}


2. Fuga de Memoria

Problema: La memoria se asigna mediante new/malloc pero no se libera mediante delete/free. Con el tiempo, la aplicación consume toda la RAM disponible.

void con_fuga() {    int* datos = new int[1000];    // Olvidó delete[] datos;}

Consecuencias: Denegación de servicio (DoS), ralentización del sistema.

Protección: Usar punteros inteligentes (std::unique_ptr, std::shared_ptr), RAII (Resource Acquisition Is Initialization).

#include <memory>void segura() {    std::unique_ptr<int[]> datos = std::make_unique<int[]>(1000);    // La memoria se liberará automáticamente al salir de la función}


3. Desreferencia de Puntero Nulo

Problema: Intento de acceder a memoria en la dirección nullptr.

void procesar(int* ptr) {    *ptr = 42; // Si ptr == nullptr, el programa fallará}

Consecuencias: Caída inmediata (fallo de segmentación), DoS.

Protección: Siempre verificar los punteros antes de usar o usar referencias.

void segura(int* ptr) {    if (ptr) {        *ptr = 42;    } else {        // Manejo de errores    }}


4. Desbordamiento de Enteros

Problema: El resultado de una operación aritmética excede el rango del tipo de dato. Esto puede provocar comportamiento impredecible, especialmente al trabajar con índices de arrays.

#include <cstdint>void vulnerable() {    uint16_t a = 65535;    uint16_t b = 1;    uint16_t suma = a + b; // Desbordamiento: 65536 -> 0}

Consecuencias: Errores lógicos, desbordamiento de búfer (si se usa para cálculo de tamaño).

Protección: Usar tipos de ancho fijo (int32_t, int64_t), verificar

Blogs

Book Recommendations