Segurança PHP: como proteger seu site contra SQL Injection e XSS

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

Seu site PHP na mira: por que hackers amam segurança fraca

\n\n

Imagine: você passou semanas desenvolvendo um blog ou loja virtual incrível em PHP. O site funciona, os visitantes estão satisfeitos. Mas em um "belo" dia, você entra no painel administrativo e encontra... vazio. O banco de dados foi deletado. Ou, pior ainda, na página principal há um anúncio de cassino e todos os usuários são redirecionados para um site de phishing.

\n\n

História familiar? Infelizmente, para muitos desenvolvedores PHP iniciantes (e não só), isso é realidade. O mais irritante é que 90% desses ataques ocorrem devido a duas vulnerabilidades aparentemente simples: SQL Injection e Cross-Site Scripting (XSS). Hackers não quebram algoritmos de criptografia complexos — eles simplesmente aproveitam a falta de atenção dos programadores.

\n\n

Neste artigo, não vamos dar palestras chatas. Vamos entender como esses ataques funcionam "por dentro" e, o mais importante, aprender a criar bloqueios sólidos. Você descobrirá como tornar seu código PHP um osso duro de roer para os invasores. Vamos lá!

\n\n

SQL Injection: quando o banco de dados fala com a voz do hacker

\n\n

SQL Injection é um tipo de ataque onde o invasor "injeta" código SQL malicioso em uma consulta ao banco de dados. Se sua aplicação não filtrar os dados de entrada, o hacker pode fazer o banco de dados executar qualquer comando: desde roubar senhas até deletar tabelas completamente.

\n\n

Como é o código vulnerável?

\n\n

Imagine um formulário de login simples. O código de um iniciante geralmente se parece com isso:

\n\n
<?php\n$login = $_POST['login'];\n$password = $_POST['password'];\n\n// PERIGOSO! Inserção direta na consulta\n$query = "SELECT * FROM users WHERE login = '$login' AND password = '$password'";\n$result = mysqli_query($link, $query);\n?>
\n\n

Parece lógico. Mas o que acontece se o invasor inserir no campo de login a seguinte string:

\n\n
' OR '1'='1
\n\n

A consulta se torna:

\n\n
SELECT * FROM users WHERE login = '' OR '1'='1' AND password = '...'
\n\n

A condição '1'='1' é sempre verdadeira. Parabéns, o hacker acabou de entrar no sistema sem senha! E se ele inserir '; DROP TABLE users; --, sua tabela de usuários desaparecerá para sempre.

\n\n

Escape vs. Consultas Preparadas: o que escolher?

\n\n

Muitos tutoriais antigos recomendam usar a função mysqli_real_escape_string(). Sim, ela escapa caracteres especiais, mas isso é coisa do passado. Este método tem desvantagens:

\n\n
    \n
  • É fácil esquecer de aplicar a função a cada variável.
  • \n
  • Não protege contra todos os tipos de injeção (por exemplo, ao trabalhar com LIKE).
  • \n
  • O código fica confuso e difícil de manter.
  • \n
\n\n

A maneira moderna e correta é usar consultas preparadas (prepared statements) via PDO ou MySQLi. Elas separam a lógica da consulta dos dados. O banco de dados primeiro "compila" o modelo da consulta e depois insere os dados nele. Mesmo que o hacker envie código malicioso, ele será tratado como uma string comum, não como parte do comando SQL.

\n\n

Escrevendo código seguro com PDO

\n\n

Aqui está como deve ser uma consulta segura ao banco de dados usando PDO (PHP Data Objects):

\n\n
<?php\n// Conexão ao BD\n$dsn = 'mysql:host=localhost;dbname=mydb;charset=utf8mb4';\n$pdo = new PDO($dsn, 'user', 'password');\n\n// Configuração do modo de erros (IMPORTANTE para depuração, mas em produção removemos)\n$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n\n// Preparação da consulta (modelo)\n$stmt = $pdo->prepare("SELECT * FROM users WHERE login = :login AND password = :password");\n\n// Vinculação de parâmetros e execução\n$stmt->execute([\n    ':login' => $_POST['login'],\n    ':password' => $_POST['password']\n]);\n\n$user = $stmt->fetch();\n\nif ($user) {\n    echo "Bem-vindo!";\n} else {\n    echo "Login ou senha inválidos";\n}\n?>
\n\n

So

Blogs

Book Recommendations