SQL Injection e as funções de escape no php
| Deixe um comentário e acompanhe a discussão assinando a feed deste ou de todos os posts e comentários. |
Acredito que todos que acompanham este blog e até mesmo quem tenha qualquer contato com desenvolvimento WEB saiba o que é um SQL Injection e o que se deve evitar para combatê-lo, porém, todos os dias eu me deparo com técnicas ineficazes para tratamento de ataques de SQL Injection baseados na dupla php e MySQL.
A maioria destas técnicas para tratamento de SQL Injection fazem referência a funções de escape ou o popular magic_quotes do php, porém poucos devem saber que estas técnicas são ineficazes para evitar este tipo de ataque. A simples adição de uma barra invertida (" \ ") em uma string que contenha um apóstrofo (" ' ") não irá eliminar a possibilidade de exploração de ataques baseados em SQL Injection.
As funções de escape mais conhecidas são addslashes() e mysql_real_escape_string(). Estas funções irão fazer a seguinte transformação em uma string.
String normal = 'admin'
String com escape = \'admin\'
Agora o que poucos sabem é que o MySQL possibilita que você faça consultas de caracteres baseados na tabela ascii. Execute no MySQL a query: select ascii('a'); e você terá a o código da letra a que é 97. Agora faça o oposto, execute a query: select char(97); e você terá o caracter a. Isso quer dizer que podemos representar strings SQL usando os códigos ascii. Se usarmos a função concat() podemos montar uma query inteira usando os códigos ascii.
Execute a seguinte query no MySQL:
select concat(char(39), char(104), char(116), char(116), char(112), char(58), char(47), char(47), char(119), char(97), char(103), char(110), char(101), char(114), char(101), char(108), char(105), char(97), char(115), char(46), char(99), char(111), char(109), char(39))
O resultado será:
'http://wagnerelias.com'
Reparem que na string criada usando a função concat não é representado o apóstrofo (" ' "), com isso as funções de escape não teriam efeito algum. Portanto, cuidado com as funções de escape, muitas vezes elas não irão lhe salvar de um ataque de SQL Injection. Sempre que possível use Bind Variables implementando as Prepared Statements do MySQL.
Comments(17)
Ulisses Castro on December 2nd, 2008
Opa! Bele artigo again Wagner, adicionando um pouco de info..
além da famosa funcao char(), ainda temos a funcão hex() e a unhex(), mas as vezes nem é preciso utilizá-las, bastando converter para hex em qualquer lugar e socar na consulta ex:
select concat(user,0xa,password) from 0x6d7973716c2e75736572;
sendo:
0x6d7973716c2e75736572 == mysql.user
As funcoes que citou não protejem contra ataques de SQL Injection sem dúvida.. mas olhando para o cenário que montou PHP + MySQL elas são de grande utilidade contra duas funcionalidades que eu poderia chamar de “chave” em um ataque, que são:
select concat(user,0xa,password) from 0x6d7973716c2e75736572 into outfile “/var/www”;
OU pior…
select “” into dumpfile “/var/www”;
Tanto dumpfile como outfile EXIGEM que sejam utilizado aspas, se não utilizar as funções que falou o servidor estará desprotegido contra um possível fuzzing para procurar diretórios que estejam com permissao incorreta e subir um backdoor…
Fica as meus dois cents!
Grande abraço!
Ulisses Castro on December 2nd, 2008
Putz no segundo exemplo do dumpfile era pra ter ficado:
select “” into dumpfile “/var/www”
duh! a página removeu meu codigo php
[]‘s
Ulisses Castro on December 2nd, 2008
aaaaaaarg!!! mal o spam…
select “codigoPHPaqui” into dumpfile “/var/www”
Elias Wagner on December 2nd, 2008
Fala Ulisses, obrigado pelo complemento….
P.s.: Ainda bem que o wordpress limita a injeção de código, você não pode ver parâmetro…
Abs.
João Marcus on December 2nd, 2008
Por que não usar Prepared Statements de uma vez? Elas têm uma performance melhor quando a query é executada várias vezes, e são realmente seguras. Você não precisa se preocupar em fazer escape de nada.
Erick on December 2nd, 2008
Cara muito bom o post, tem muitos programadores que acabam expondo sistemas com vulnerabilidades na internet, e soluções fáceis podem resolver o problema.
Falow, t+
Carlos André Ferrari on December 2nd, 2008
então se eu não permitir a utilização dessas palavras (char, hex, unhex e dumpfile) e o escape na minha consulta já deve resolver o problema para praticamente todas as situações, certo?
Ribamar FS on December 2nd, 2008
Agradecido por compartilhar seus conhecimentos.
Não sei porque usa:
“Você chegou até aqui procurando por “” através do http://www.google.com.”
Eu não cheguei aqui via Google, portanto está furado.
Douglas Cunha on December 2nd, 2008
Desenvolvo em PHP faz tempo. Sempre me preocupei em usar as funções de escape, mas nunca atentei para essa forma de ataque. Vou ficar mais esperto agora.
Muito bom o artigo. Aposto que como eu, muita gente via essas funções do MySQL (char, ascii…) com uma certa ingenuidade.
Elias Wagner on December 2nd, 2008
João Marcos,
realmente as prepared statements são uma boa opção para tratar vulnerabilidades de SQL Injection, além do ganho de performance por elas manterem um plano de execução em cache. Eu recomendo também usar prepared statements, inclusive está no texto.
Quanto ao escape, ele tem outras necessidades, por exemplo a que foi comentada pelo Ulisses.
Obrigado pelo comentário.
Elias Wagner on December 2nd, 2008
Carlos André,
eu não recomendo ficar validando, fazendo substituição de strings especificas, o melhor dos mundos é usar prepared statements e/ou fazer uma validação positiva, deixar passar apenas o conjunto de strings que você precisa e não trazem risco a aplicação.
Obrigado pelo comentário.
Elias Wagner on December 2nd, 2008
Douglas,
realmente tem muitas coisas que acabam passando despercebidas.
Obrigado pelo comentário.
Keylly Eyglys on December 2nd, 2008
Bem, achei seu post incompleto pois não falou quais os ataques que podem ser realizados mesmo realizando o escape nas aspas.
Serviu apenas para apresentar a função ascii e char do MySQL (que já deveria ser do conhecimento de muitos).
Elias Wagner on December 3rd, 2008
Keylly,
sinto não ter atendido sua expectativa. eu falei dos riscos de usar as funções de escape e o que pode-se usar para bypassar estes controles. Não falei apenas das funções de ascii e char, as funções foram apresentadas como ferramenta para burlar os controles de escape.
Se você espera o passo-a-passo de como fazer isso, sinto muito, o post não é um how-to de como fazer SQL Injection, se você pegar um script e testar vai ver o que acontece.
Obrigado pelo comentário.
Ulisses Castro on December 3rd, 2008
LOL Troll detected! o.O
Bom vendo todo mundo comentar sobre Prepared Statements e tal… é bacana e é fortemente recomendada MAAAAAAAS… lembrando que utilizando você estará delegando pro BD o processamento, portanto cuidado ao utilizá-la pois em certas circunstâncias pode acarretar em perda de performance…
Mais dois cents!
[s]
SQL Injection e as funções de escape no php on December 2nd, 2008
[...] por Wagner Elias (weliasΘconviso·com·br) – referência [...]
Making it easy! Executando query utilizando valores ascii. « Meninão on January 2nd, 2009
[...] Entenda sobre essa e outras técnicas mais efetivas aqui. [...]