Segurança em C++: Proteção contra SQL Injection e XSS em 2024

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

Quando C++ encontra a web: por que a segurança é sua maior dor de cabeça

\n\n

Você já se perguntou por que os hackers amam tanto aplicações C++? Não, não porque o código é complexo. Mas porque, na busca por desempenho, os desenvolvedores frequentemente esquecem da segurança em C++. E pagam por isso com dados de usuários, reputação e dinheiro.

\n\n

Imagine: você escreveu um servidor incrível em C++ que processa requisições mais rápido que um raio. Mas uma única entrada sem escape — e um invasor rouba todo o banco de dados. Ou, pior ainda, insere um script que rouba as sessões de todos os visitantes do site. Familiar? Se não — ótimo, significa que você está lendo este artigo na hora certa.

\n\n

Neste material, vamos analisar os dois ataques mais perigosos em aplicações web — SQL Injection e Cross-Site Scripting (XSS) — e mostrar como se proteger deles especificamente em C++. Sem mágica, com exemplos reais de código. Vamos lá.

\n\n

SQL Injection: como hackers transformam sua consulta em arma

\n\n

SQL Injection é quando um invasor insere em um campo de entrada (como login ou busca) um trecho de código SQL. Se sua aplicação simplesmente insere essa entrada na consulta, em vez de buscar um usuário pelo nome, o banco executará algo como DROP TABLE users. Ou, pior ainda, exibirá todas as senhas.

\n\n

Erro típico de iniciante (e como evitá-lo)

\n\n

Veja este código. Parece inofensivo, mas é uma bomba-relógio:

\n\n
// PERIGOSO! Nunca faça isso\nstd::string username = getUserInput(); // usuário digitou: ' OR '1'='1\nstd::string query = "SELECT * FROM users WHERE username = '" + username + "'";\n// Resultado: SELECT * FROM users WHERE username = '' OR '1'='1'\n// Retornará todos os usuários!
\n\n

Percebeu o problema? Se o usuário digitar ' OR '1'='1, a consulta retornará toda a tabela. E se digitar '; DROP TABLE users; --, então goodbye, banco de dados.

\n\n

Abordagem correta: consultas parametrizadas

\n\n

A única maneira confiável de proteção contra SQL Injection em C++ é usar consultas parametrizadas. O banco de dados diferencia automaticamente código de dados. Veja como fica com a biblioteca libpqxx (para PostgreSQL) ou MySQL Connector/C++:

\n\n
#include <iostream>\n#include <pqxx/pqxx> // libpqxx para PostgreSQL\n\nvoid safeQuery(const std::string& username) {\n    try {\n        pqxx::connection conn("dbname=mydb user=myuser password=mypass");\n        pqxx::work txn(conn);\n        \n        // Consulta parametrizada: $1 é o parâmetro\n        std::string query = "SELECT * FROM users WHERE username = $1";\n        pqxx::result result = txn.exec_params(query, username);\n        \n        for (auto row : result) {\n            std::cout << "User: " << row["username"].c_str() << std::endl;\n        }\n        txn.commit();\n    } catch (const std::exception &e) {\n        std::cerr << "Error: " << e.what() << std::endl;\n    }\n}\n\nint main() {\n    std::string input;\n    std::cout << "Enter username: ";\n    std::getline(std::cin, input);\n    safeQuery(input);\n    return 0;\n}
\n\n

Observe: usamos txn.exec_params em vez de concatenação de strings. O banco de dados escapa os caracteres especiais automaticamente. Mesmo que o usuário digite ' OR '1'='1, isso será tratado como string, e não como parte do comando SQL.

\n\n

E se você estiver usando SQLite puro?

\n\n

Mesmo com SQLite é possível trabalhar com segurança. Use sqlite3_prepare_v2 e sqlite3_bind_text:

\n\n
#include <sqlite3.h>\n#include <iostream>\n\nvoid safeSQLiteQuery(sqlite3* db, const std::string& username) {\n    sqlite3_stmt* stmt;\n    const char* sql = "SELECT * FROM users WHERE username = ?";\n    \n    if (sqlite3_prepare_v2                

Blogs

Book Recommendations