Top-10 vulnerabilidades de aplicações PHP: como proteger seu código
O PHP continua sendo uma das linguagens mais populares para desenvolvimento web. No entanto, sua flexibilidade e simplicidade frequentemente levam ao surgimento de vulnerabilidades críticas. Segundo estatísticas da OWASP, mais de 70% das aplicações web possuem pelo menos uma falha grave de segurança. Neste artigo, analisaremos as 10 vulnerabilidades mais comuns em aplicações PHP, mostraremos exemplos de código perigoso e daremos recomendações práticas de proteção.
1. SQL Injection
O ataque mais conhecido e perigoso. O invasor insere código SQL através da entrada do usuário.
Código perigoso:
<?php$id = $_GET['id'];$query = "SELECT * FROM users WHERE id = $id";$result = mysqli_query($conn, $query);?>Código seguro (uso de prepared statements):
<?php$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");$stmt->bind_param("i", $_GET['id']);$stmt->execute();$result = $stmt->get_result();?>Recomendações:
- Sempre use prepared statements (PDO ou MySQLi).
- Nunca concatene dados do usuário em consultas SQL.
- Valide tipos de dados (ex.:
is_numeric()para IDs).
2. XSS (Cross-Site Scripting)
Inserção de código JavaScript na página através de dados não validados. Roubo de cookies, redirecionamento para sites de phishing.
Código perigoso:
<?phpecho "Olá, " . $_GET['name'];?>Código seguro:
<?phpecho "Olá, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');?>Recomendações:
- Escape a saída com
htmlspecialchars(). - Configure Content-Security-Policy (CSP) nos cabeçalhos.
- Para respostas JSON, use
json_encode().
3. CSRF (Cross-Site Request Forgery)
O invasor força um usuário autenticado a executar uma ação indesejada (ex.: transferência de dinheiro).
Exemplo de formulário sem proteção:
<form action="delete.php" method="POST"> <input type="hidden" name="id" value="123"> <input type="submit" value="Excluir"></form>Código seguro (com token):
<?phpsession_start();if (empty($_SESSION['token'])) { $_SESSION['token'] = bin2hex(random_bytes(32));}?><form action="delete.php" method="POST"> <input type="hidden" name="token" value="<?= $_SESSION['token'] ?>"> <input type="hidden" name="id" value="123"> <input type="submit" value="Excluir"></form>Recomendações:
- Gere tokens CSRF únicos para cada formulário.
- Verifique os tokens no servidor antes de executar ações.
- Use SameSite Cookie (Lax ou Strict).
4. Autenticação e gerenciamento de sessão incorretos
Proteção fraca de sessões, vazamento de identificadores, fixação de sessão.
Código vulnerável:
<?phpsession_start();if ($_POST['password'] == 'admin123') { $_SESSION['logged'] = true;}?>Código seguro:
<?phpsession_start();session_regenerate_id(true); // Troca o ID da sessão após o login
// Hash da senha$hash = password_hash($_POST['password'], PASSWORD_BCRYPT);if (password_verify($input_password, $hash)) { $_SESSION['logged'] = true; $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];}?>Recomendações:
- Use
password_hash()epas