- Wagner Elias – Think Security First - http://wagnerelias.com -

SQL Injection e as funções de escape no php

Posted By Elias Wagner On 1 01America/Denver December, 2008 @ 6:54 pm In Security Developer | 17 Comments

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 [1] 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() [2] e mysql_real_escape_string() [3]. 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 [4]. 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 [5] do MySQL.


17 Comments (Open | Close)

17 Comments To "SQL Injection e as funções de escape no php"

#1 Comment By Ulisses Castro On 2 02America/Denver December, 2008 @ 9:59 am

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 0×6d7973716c2e75736572;

sendo:
0×6d7973716c2e75736572 == 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 0×6d7973716c2e75736572 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!

[6] [6]

#2 Comment By Ulisses Castro On 2 02America/Denver December, 2008 @ 10:03 am

Putz no segundo exemplo do dumpfile era pra ter ficado:

select “” into dumpfile “/var/www”

duh! a página removeu meu codigo php :)

[]’s

[6] [6]

#3 Comment By Ulisses Castro On 2 02America/Denver December, 2008 @ 10:06 am

aaaaaaarg!!! mal o spam…

select “codigoPHPaqui” into dumpfile “/var/www”

[6] [6]

#4 Comment By Elias Wagner On 2 02America/Denver December, 2008 @ 10:23 am

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.

[6] [6]

#5 Comment By João Marcus On 2 02America/Denver December, 2008 @ 12:22 pm

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.

[6] [6]

#6 Comment By Erick On 2 02America/Denver December, 2008 @ 12:39 pm

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+

[6] [6]

#7 Comment By Carlos André Ferrari On 2 02America/Denver December, 2008 @ 12:51 pm

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?

[6] [6]

#8 Comment By Ribamar FS On 2 02America/Denver December, 2008 @ 12:52 pm

Agradecido por compartilhar seus conhecimentos.

Não sei porque usa:
“Você chegou até aqui procurando por “” através do [7].”

Eu não cheguei aqui via Google, portanto está furado.

[6] [6].\"\r\n\r\nEu não cheguei aqui via Google, portanto está furado.’); return false;”>Quote

#9 Comment By Douglas Cunha On 2 02America/Denver December, 2008 @ 3:16 pm

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.

[6] [6]

#10 Comment By Elias Wagner On 2 02America/Denver December, 2008 @ 6:54 pm

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.

[6] [6]

#11 Comment By Elias Wagner On 2 02America/Denver December, 2008 @ 6:56 pm

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.

[6] [6]

#12 Comment By Elias Wagner On 2 02America/Denver December, 2008 @ 6:59 pm

Douglas,

realmente tem muitas coisas que acabam passando despercebidas. :)

Obrigado pelo comentário.

[6] [6]

#13 Comment By Keylly Eyglys On 2 02America/Denver December, 2008 @ 11:58 pm

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).

[6] [6]

#14 Comment By Elias Wagner On 3 03America/Denver December, 2008 @ 12:44 pm

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.

[6] [6]

#15 Comment By Ulisses Castro On 3 03America/Denver December, 2008 @ 1:49 pm

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]

[6] [6]

#16 Pingback By SQL Injection e as funções de escape no php On 2 02America/Denver December, 2008 @ 11:03 am

[...] por Wagner Elias (weliasΘconviso·com·br) – referência [...]

[6] [6]

#17 Pingback By Making it easy! Executando query utilizando valores ascii. « Meninão On 2 02America/Denver January, 2009 @ 11:47 pm

[...] Entenda sobre essa e outras técnicas mais efetivas aqui. [...]

[6] [6]

Article printed from Wagner Elias – Think Security First: http://wagnerelias.com

URL to article: http://wagnerelias.com/2008/12/01/sql-injection-e-as-funcoes-de-escape-no-php/

URLs in this post:

[1] magic_quotes: http://br.php.net/magic_quotes

[2] addslashes(): http://br.php.net/manual/pt_BR/function.addslashes.php

[3] mysql_real_escape_string(): http://br.php.net/manual/pt_BR/function.mysql-real-escape-string.php

[4] tabela ascii: http://www.asciitable.com/

[5] Prepared Statements: http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

[6] : #

[7] : http://www.google.com

Copyright © 2007 Wagner Elias - Think Security First | BCP, BIA, DRP, Security Assessment, Risk Assessment, Security Developer. All rights reserved.