Como evitar ataques de injeção SQL em PHP?
A injeção SQL é uma das vulnerabilidades mais exploradas por hackers para obter acesso a bancos de dados. No PHP, a maneira mais segura de evitar esse tipo de ataque é utilizando Prepared Statements com PDO ou MySQLi.
O perigo das consultas SQL inseguras
O seguinte código vulnerável demonstra um exemplo clássico de injeção SQL:
<?php
$conexao = new mysqli("localhost", "usuario", "senha", "banco");
$usuario = $_POST['usuario'];
$senha = $_POST['senha'];
$query = "SELECT * FROM usuarios WHERE usuario = '$usuario' AND senha = '$senha'";
$resultado = $conexao->query($query);
?>
Se um usuário mal-intencionado inserir ' OR '1'='1
no campo usuario
, o SQL será executado de forma que sempre retornará um resultado válido.
Protegendo com Prepared Statements (PDO)
O uso de Prepared Statements evita esse problema ao separar os dados do SQL:
<?php
$conexao = new PDO("mysql:host=localhost;dbname=banco", "usuario", "senha");
$stmt = $conexao->prepare("SELECT * FROM usuarios WHERE usuario = :usuario AND senha = :senha");
$stmt->bindParam(":usuario", $_POST["usuario"]);
$stmt->bindParam(":senha", $_POST["senha"]);
$stmt->execute();
?>
Aqui, os valores são tratados como dados, não como parte da instrução SQL, eliminando o risco de injeção.
Protegendo com Prepared Statements (MySQLi)
Se preferirmos usar MySQLi, a abordagem segura é:
<?php
$conexao = new mysqli("localhost", "usuario", "senha", "banco");
$stmt = $conexao->prepare("SELECT * FROM usuarios WHERE usuario = ? AND senha = ?");
$stmt->bind_param("ss", $_POST['usuario'], $_POST['senha']);
$stmt->execute();
?>
Essa técnica também protege contra injeção SQL ao parametrizar as consultas.
Por que usar Prepared Statements para evitar SQL Injection?
A injeção SQL é um dos ataques mais comuns em aplicações web e pode comprometer toda a base de dados se não for prevenida. O uso de Prepared Statements com PDO ou MySQLi é a maneira mais eficaz de evitar esse tipo de ataque. Além disso, nunca confie em dados vindos de formulários sem sanitizá-los adequadamente, garantindo que sua aplicação esteja protegida contra invasores.
Algumas aplicações:
- Proteção contra ataques mal-intencionados em sistemas de login
- Sanitização de consultas dinâmicas antes de enviá-las ao banco de dados
- Prevenção contra exclusão ou modificação indesejada de dados
- Melhoria na segurança de qualquer aplicação PHP que interaja com bancos de dados
Dicas para quem está começando
- Sempre utilize Prepared Statements ao manipular bancos de dados no PHP.
- Evite concatenar diretamente variáveis de usuário nas queries SQL.
- Utilize
htmlspecialchars()
para sanitizar saídas e evitar ataques XSS. - Não armazene senhas em texto puro, utilize hashing com
password_hash()
. - Monitore logs de acesso e erros para identificar possíveis tentativas de invasão.
Contribuições de Daniel Moreira