Segurança de aplicações C++: top 10 vulnerabilidades para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Segurança de aplicações C++: top 10 vulnerabilidades para iniciantes

\n\n

A linguagem C++ dá ao desenvolvedor um enorme controle sobre a memória e o desempenho, mas essa liberdade também traz uma grande responsabilidade. De acordo com OWASP e CWE, vulnerabilidades em aplicações C++ geralmente surgem devido ao gerenciamento incorreto de memória, falta de verificação de limites e descuido ao trabalhar com ponteiros. Neste artigo, abordaremos as 10 vulnerabilidades mais comuns que os iniciantes enfrentam. Você aprenderá como detectá-las e, principalmente, como evitá-las.

\n\n

1. Estouro de buffer (Buffer Overflow)

\n

Um clássico do gênero. Essa vulnerabilidade ocorre quando o programa escreve dados além dos limites do buffer alocado. Um invasor pode sobrescrever áreas de memória adjacentes, incluindo o endereço de retorno da função, e obter controle sobre a execução do código.

\n\n
// Código vulnerável\nvoid vulnerable() {\n    char buffer[10];\n    std::cout << "Digite uma string: ";\n    std::cin >> buffer; // Sem verificação de tamanho!\n    std::cout << buffer << std::endl;\n}\n\n// Versão segura\nvoid safe() {\n    char buffer[10];\n    std::cout << "Digite uma string: ";\n    std::cin.getline(buffer, sizeof(buffer));\n    std::cout << buffer << std::endl;\n}
\n\n

Como se proteger: Sempre use funções com limitação de tamanho (strncpy, snprintf, std::string). Evite gets() e strcpy().

\n\n

2. Vazamentos de memória (Memory Leaks)

\n

Se você alocou memória com new, mas esqueceu de liberá-la com delete, o programa consumirá gradualmente a memória RAM. Para aplicações de servidor, isso é um desastre — após algumas horas de operação, o serviço falhará com o erro std::bad_alloc.

\n\n
// Exemplo de vazamento\nvoid leak() {\n    int* ptr = new int(42);\n    // Esqueceu delete ptr;\n}\n\n// Abordagem correta\nvoid noLeak() {\n    std::unique_ptr<int> ptr = std::make_unique<int>(42);\n    // A memória será liberada automaticamente ao sair do escopo\n}
\n\n

Como se proteger: Use ponteiros inteligentes (std::unique_ptr, std::shared_ptr). Em último caso, use RAII (Resource Acquisition Is Initialization).

\n\n

3. Ponteiros soltos (Dangling Pointers)

\n

Um ponteiro referencia uma memória já liberada. Desreferenciar tal ponteiro é um comportamento indefinido (UB). Isso pode causar uma falha no programa ou, pior, a execução de código malicioso.

\n\n
int* dangling() {\n    int x = 10;\n    return &x; // Erro: retornando o endereço de uma variável local!\n}\n\n// Correto — alocar memória no heap\nint* safe() {\n    int* ptr = new int(10);\n    return ptr;\n}
\n\n

Como se proteger: Após delete, sempre atribua nullptr ao ponteiro. Use ponteiros inteligentes.

\n\n

4. Estouro de inteiros (Integer Overflow)

\n

Quando o resultado de uma operação aritmética ultrapassa os limites do tipo de dados, ocorre um estouro. Isso pode levar a consequências inesperadas, como a alocação de um buffer muito pequeno.

\n\n
void check_size(size_t user_size) {\n    // Vulnerabilidade: se user_size for muito grande, user_size + 1 pode se tornar pequeno\n    char* buffer = new char[user_size + 1];\n    // ...\n}\n\n// Proteção\nvoid safe_check(size_t user_size) {\n    if (user_size > std::numeric_limits<size_t>::max() - 1) {\n        throw std::overflow_error("Tamanho muito grande");\n    }\n    char* buffer = new char[user_size + 1];\n}
\n\n

Como se proteger: Verifique os limites antes de operações aritméticas. Use __builtin_add_overflow (GCC/Clang) ou bibliotecas para aritmética segura.

\n\n

5. Ponteiros nulos (Null Pointer Dereference)

\n

Desreferenciar um ponteiro nulo

Blogs

Book Recommendations