Segurança de aplicações C++: top 10 vulnerabilidades e formas de proteção

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 e formas de proteção



C++ é uma linguagem de programação de sistemas poderosa, mas sua flexibilidade e acesso direto à memória tornam as aplicações vulneráveis a ataques graves. De acordo com OWASP e CWE, muitas vulnerabilidades críticas em software industrial (de jogos a aviônica) surgem precisamente devido a erros no código C++. Neste artigo, analisaremos as 10 vulnerabilidades mais perigosas, forneceremos exemplos de código e mostraremos como evitá-las.



1. Estouro de buffer (Buffer Overflow)

Vulnerabilidade clássica que permite ao invasor sobrescrever áreas adjacentes da memória. Ocorre ao copiar dados sem verificar o tamanho.



// Código vulnerável#include <cstring>void vulnerable(char* input) {    char buffer[10];    strcpy(buffer, input); // Perigo: se input for maior que 9 caracteres}// Versão seguravoid secure(char* input, size_t len) {    char buffer[10];    if (len < sizeof(buffer)) {        strncpy(buffer, input, sizeof(buffer) - 1);        buffer[sizeof(buffer) - 1] = '\\0';    }}


Proteção: use std::string, std::vector ou funções com limite de comprimento (strncpy, snprintf). Ative as flags do compilador -fstack-protector-strong e -D_FORTIFY_SOURCE=2.



2. Uso após liberação (Use-After-Free)

Acesso à memória que já foi liberada. Leva à leitura/escrita em área alheia ou à execução de código arbitrário.



// Código vulnerávelint* ptr = new int(42);delete ptr;*ptr = 100; // Erro! ptr não é mais válido// Versão seguraint* ptr = new int(42);delete ptr;ptr = nullptr; // Zeramos o ponteiroif (ptr) *ptr = 100; // Verificação antes do uso


Proteção: use smart pointers (std::unique_ptr, std::shared_ptr), zere raw pointers após delete, aplique sanitizers (-fsanitize=address).



3. Estouro de inteiro (Integer Overflow)

Ultrapassar os limites da faixa permitida em operações aritméticas. Frequentemente usado para contornar verificações de tamanho de buffer.



// Código vulnerávelsize_t size = 0;size_t user_input = 4294967295; // 2^32 - 1size_t total = size + user_input + 1; // Estouro!// Versão segura com verificaçãoif (user_input > SIZE_MAX - size) {    throw std::overflow_error("Tamanho muito grande");}size_t total = size + user_input + 1;


Proteção: use tipos de largura fixa (uint32_t), verifique o estouro antes da operação, aplique __builtin_add_overflow (GCC/Clang).



4. Desreferência de ponteiro nulo (Null Pointer Dereference)

Tentativa de acessar a memória no endereço NULL. Leva ao encerramento abrupto do programa (segfault) ou a uma vulnerabilidade DoS.



// Código vulnerávelvoid process(int* ptr) {    *ptr = 10; // Se ptr == nullptr — crash}// Versão seguravoid process(int* ptr) {    if (!ptr) {        throw std::invalid_argument("Ponteiro nulo recebido");    }    *ptr = 10;}


Proteção: sempre verifique ponteiros para nullptr antes do uso, retorne std::optional em vez de raw pointers.



5. Vazamentos de memória (Memory Leaks)

Perda de acesso à memória alocada sem sua liberação. Com o tempo, esgota os recursos do sistema.



// Código vulnerávelvoid leak() {    int* data = new int[100];    // Esquecemos delete[] data — vazamento}// Versão seguravoid no_leak() {    std::unique_ptr<int[]> data = std::make_unique<int[]>(100);    // A memória será liberada automaticamente}


Proteção: use RAII (smart pointers, containers

Blogs

Book Recommendations