Alguém poderia me dizer se é seguro ou se é vulnerável ao ataque SQL Injection ou outros ataques SQL?
Não. Como diz o uri2x, veja Injeção de SQL que contorna
mysql_real_escape_string()
. A melhor maneira para evitar a injeção de SQL é usar instruções preparadas. Eles separam os dados (seus parâmetros) das instruções (a string de consulta SQL) e não deixam espaço para que os dados contaminem a estrutura de sua consulta. Declarações preparadas resolvem um dos problemas fundamentais de segurança de aplicativos .
Para situações em que você não pode usar instruções preparadas (por exemplo,
LIMIT
), usar uma lista de permissões muito rígida para cada finalidade específica é a única maneira de garantir segurança. // This is a string literal whitelist
switch ($sortby) {
case 'column_b':
case 'col_c':
// If it literally matches here, it's safe to use
break;
default:
$sortby = 'rowid';
}
// Only numeric characters will pass through this part of the code thanks to type casting
$start = (int) $start;
$howmany = (int) $howmany;
if ($start < 0) {
$start = 0;
}
if ($howmany < 1) {
$howmany = 1;
}
// The actual query execution
$stmt = $db->prepare(
"SELECT * FROM table WHERE col = ? ORDER BY {$sortby} ASC LIMIT {$start}, {$howmany}"
);
$stmt->execute(['value']);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
Eu postulo que o código acima é imune à injeção de SQL, mesmo em casos de borda obscuros. Se você estiver usando o MySQL, certifique-se de desativar as preparações emuladas.
$db->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);