O manual parece sugerir que usar aspas em torno de números é suficiente para proteger da injeção de SQL.
De acordo com a seção 5.3.1. Diretrizes Gerais de Segurança do Manual de Referência do MySQL 5.1 :
Se um aplicativo gera uma consulta, como
SELECT * FROM table WHERE ID=234
quando um usuário insere o valor234
, o usuário pode inserir o valor234 OR 1=1
para fazer com que o aplicativo gere a consultaSELECT * FROM table WHERE ID=234 OR 1=1
. Como resultado, o servidor recupera todas as linhas da tabela. Isso expõe cada linha e causa carga excessiva do servidor. A maneira mais simples de se proteger desse tipo de ataque é usar aspas simples em volta das constantes numéricas:SELECT * FROM table WHERE ID='234'
. Se o usuário inserir informações extras, tudo se tornará parte da string. Em um contexto numérico, o MySQL converte automaticamente essa string em um número e retira dela quaisquer caracteres não numéricos à direita.
Isso significa que o usuário está protegido se inserir o valor 234' OR 1=1 #
? (ou seja, para gerar a consulta SELECT * FROM table WHERE ID='234' OR 1=1 #'
)
Resposta curta, não. O truque das citações é facilmente derrotado incluindo sua própria citação de fechamento e, em seguida, um símbolo de comentário para eliminar a citação concatenada final, exatamente como no seu exemplo.
Para se proteger da injeção de SQL, você deve usar variáveis de ligação . Alterar seu exemplo para
SELECT * FROM table WHERE ID = :X
e vincular a entrada do usuário a X resolve o problema instantânea e completamente. É impossível enfatizar demais a importância dessa prática!O usuário só precisa entrar
234' OR 1=1 --
(com o espaço à direita) para quebrar isso.O trecho fornecido acima não impedirá injeções de SQL. Mesmo com aspas simples, a entrada pode ser modificada para manipular as aspas. Com aspas a consulta será:
SELECT * FROM tabela WHERE ID='234', onde a entrada é
234
Agora considere a entrada injetada:
234'; select * from passwords;select * from table where id='234
. Isso criará um bloco de consulta de:SELECT * FROM tabela WHERE ID='234'; selecione * das senhas;selecione * da tabela onde id='234'
Dependendo da linguagem de front-end usada, no meu caso PHP, existem funções incorporadas como
mysql_real_escape_string
essa que podem ser usadas para reduzir as injeções de SQL. O único comentário que posso dizer sobre a documentação (além do humorístico de @mrdenny) é que sem as aspas, há mais injeção possível.Geralmente, não é uma "diretriz" tão ruim se você estiver usando algum tipo de
magic_quotes
mecanismo (que pode ser contornado apenas se você estiver usandoGBK / Big5
um ou conjuntos de caracteres familiares no DBMS de back-end). Ele deve filtrar/pré-formatar adequadamente todas as ocorrências de caracteres'
que podem inserir facilmente a injeção SQL nessa instrução (por exemplo, com carga útil que você declarou234' OR 1=1 #
).Mas, para estar 100% seguro, você definitivamente deve usar APENAS instruções SQL "parametrizadas"!