Protegendo seu código PHP contra SQL Injection

Mantenha seu código seguro e evite ataques em seu site ou aplicação

01/01/2024

Protegendo seu código PHP contra SQL Injection

Protegendo seu código PHP contra SQL Injection

Entenda como funciona este tipo de ataque

SQL Injection é um ataque que permite a invasores modificar operações de banco de dados através de um aplicativo. Isso pode resultar em acesso indevido e manipulação de dados, incluindo a exclusão de tabelas ou alteração de senhas de usuários.

Aqui está um exemplo de código PHP vulnerável a SQL Injection, com um parâmetro de URL:

// Exemplo de código PHP vulnerável a SQL Injection
// Recebendo 'id' da URL
$id = $_GET['id'];
// Montagem insegura da consulta
$query = "SELECT * FROM users WHERE id = $id"; 
// Execução da consulta...

Este código é vulnerável porque usa diretamente um dado externo ('id' da URL) na consulta SQL. Por exemplo, se o parâmetro 'id' da URL for alteradp para id=0; DROP TABLE users;, a consulta se tornará SELECT * FROM users WHERE id = 0; DROP TABLE users;, resultando na exclusão da tabela 'users' e perda de todos os dados.

Protegendo Seu Código de SQL Injection com PDO

Utilizar PDO (PHP Data Objects) com named parameters é uma maneira eficiente de proteger seu código PHP contra SQL Injection. Vamos aprimorar nosso código inicial com o uso de PDO:

// Protegendo o código com PDO
// Estabelecendo conexão PDO
$pdo = new PDO('mysql:host=localhost;dbname=banco', 'usuario', 'senha');
// Garantindo que 'id' seja um número inteiro
$id = (int) $_GET['id']; 
// Preparando a consulta com named parameter
$query = "SELECT * FROM users WHERE id = :id"; 
$stmt = $pdo->prepare($query);
// Executando a consulta com um parâmetro seguro
$stmt->execute(['id' => $id]);
// Código para manipulação dos resultados...

Ao converter o 'id' para um inteiro, garantimos que apenas valores numéricos sejam usados na consulta, adicionando uma camada extra de segurança.

Protegendo Seu Código de SQL Injection com MySQLi

Embora o MySQLi não permita a vinculação de parâmetros diretamente no execute como o PDO, ele ainda é uma ferramenta segura contra SQL Injection. Vamos ver como usar o MySQLi com segurança:


// Protegendo o código com MySQLi
// Conectando ao banco de dados com MySQLi
$mysqli = new mysqli('localhost', 'usuario', 'senha', 'banco');
// Garantindo que 'id' seja um número inteiro
$id = (int) $_GET['id'];
// Preparando a consulta
$query = "SELECT * FROM users WHERE id = ?"; 
$stmt = $mysqli->prepare($query);
// Vinculando parâmetro 'id' como inteiro
$stmt->bind_param('i', $id);
// Executando a consulta segura
$stmt->execute();
// Código para manipulação dos resultados...

Usando o `bind_param`, vinculamos o 'id' de forma segura à consulta, prevenindo a injeção de SQL.

Lidando com MySQL em Sistemas Legados

Para sistemas legados que ainda utilizam a biblioteca mysql, é importante manter a segurança. Veja um exemplo de código seguro:

// Protegendo sistemas legados com
$conexao = mysql_connect('localhost', 'usuario', 'senha');
mysql_select_db('banco', $conexao);
// Usando escape diretamente na consulta SQL
$id = (int) $_GET['id'];
$query = "SELECT * FROM users WHERE id = " . mysql_real_escape_string($id, $conexao);
$resultado = mysql_query($query);
// Código para manipulação dos resultados...
mysql_close($conexao);

Mesmo em sistemas legados, é possível manter a segurança, garantindo que os parâmetros sejam tratados de forma segura e utilizando validações.

Usando as Funções filter_var() e filter_input() para Proteção Adicional

As funções filter_var e filter_input do PHP são ferramentas essenciais para validar e filtrar dados de entrada. Elas oferecem diversos filtros e validações, garantindo a segurança e o formato adequado dos dados recebidos.

Utilizando filter_var()

filter_var é usada para filtrar e validar dados já existentes em variáveis. Por exemplo, para validar um e-mail:

// Validando um e-mail com filter_var
$email = $_POST['email'];
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // E-mail válido
    // Processamento adicional...
} else {
    // E-mail inválido
    // Tratamento de erro...
}

E para filtrar um número inteiro:

// Filtrando um inteiro com filter_var
$idade = $_POST['idade'];
$idadeFiltrada = filter_var($idade, FILTER_SANITIZE_NUMBER_INT);
// Utilizar $idadeFiltrada em operações seguras...

Utilizando filter_input()

filter_input é usada para coletar e validar dados diretamente da fonte de entrada (como GET e POST), oferecendo uma abordagem mais segura. Por exemplo, para obter e validar um número inteiro via GET:

// Validando um inteiro com filter_input
$idade = filter_input(INPUT_GET, 'idade', FILTER_VALIDATE_INT);
if ($idade !== false) {
    // Idade válida ou zero
    // Processamento adicional...
} else {
    // Idade inválida
    // Tratamento de erro...
}

Da mesma forma, para validar um e-mail recebido via POST:

// Validando um e-mail com filter_input
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email !== false) {
    // E-mail válido ou em branco
    // Processamento adicional...
} else {
    // E-mail inválido
    // Tratamento de erro...
}

Conclusão: filter_var e filter_input são ferramentas poderosas para garantir a integridade e a segurança dos dados manipulados em aplicações PHP. Utilizar a comparação estrita com `false` é essencial para diferenciar entre uma entrada inválida e uma entrada em branco ou zero.

Conclusão

Proteger seu código PHP contra SQL Injection é fundamental para garantir a segurança de suas aplicações. Neste artigo, abordamos técnicas para evitar essa vulnerabilidade, incluindo o uso de PDO, MySQLi e proteção em sistemas legados com mysql.

Lembre-se sempre de validar e tratar os dados de entrada, evitando concatenação direta em consultas SQL. A segurança de suas aplicações depende dessas práticas, evitando potenciais ataques e prejuízos.

Domínios hospedados
Clientes satisfeitos