Qualquer consulta pode ser injetada, seja de leitura ou gravação, persistente ou transitória. As injeções podem ser realizadas terminando uma consulta e executando uma outra separada (possível com
mysqli
), o que torna a consulta pretendida irrelevante. Qualquer entrada para uma consulta de uma fonte externa, seja de usuários ou mesmo interna, deve ser considerada um argumento para a consulta e um parâmetro no contexto da consulta. Qualquer parâmetro em uma consulta precisa ser parametrizado. Isso leva a uma consulta parametrizada corretamente da qual você pode criar uma instrução preparada e executar com argumentos. Por exemplo:
SELECT col1 FROM t1 WHERE col2 = ?
?
é um espaço reservado para um parâmetro. Usando mysqli
, você pode criar uma instrução preparada usando prepare
, vincule uma variável (argumento) a um parâmetro usando bind_param
, e execute a consulta com execute
. Você não precisa desinfetar o argumento (na verdade, é prejudicial fazê-lo). mysqli
faz isso por você. O processo completo seria:$stmt = $mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();
Há também uma distinção importante entre consulta parametrizada e declaração preparada . Esta declaração, enquanto preparada, não é parametrizada e, portanto, é vulnerável à injeção:
$stmt = $mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");
Para resumir:
- Todos As consultas devem ser parametrizadas corretamente (a menos que não tenham parâmetros)
- Todos argumentos para uma consulta devem ser tratados o mais hostil possível, independentemente de sua fonte