rvlira 0 Denunciar post Postado Dezembro 4, 2008 Pessoal, para evitar problemas de sql e php injection estou utilizando a seguinte função para tratar tudo que o script recebe de formulários e parâmetros via query string: function anti_injection($txt){ $txt = get_magic_quotes_gpc() == 0 ? addslashes($txt) : $txt; return preg_replace("@(--|\#|\*|;|=)@s", "", $txt); } function processaString($texto){ return anti_injection(strip_tags($texto)); } O primeiro teste que fiz com essa função foi na página de login. No campo nome de usuário digitei: fulano' or 1=1 No campo de login digitei: teste' or 1=1 Na página que valida o login eu tenho: $nome = processaString($_REQUEST['username']); $senha = processaString($_REQUEST['password']); $sql = "SELECT SENHA FROM USUARIOS WHERE LOGIN='".$nome."'"; #Notem que estou colocando o login entre aspas simples acima Bem, o banco de dados que estou usando é o firebird. Eu achava que essa função anti-injection fosse tratar toda a string passada pelo usuário como uma string, ou seja, removendo aspas simples e duplas. Mas rodando o exemplo acima, colocando aspas simples no campo de login ou senha o script apresenta erro porque considerou a aspas simples quando deveria bloqueá-la. Poderiam me ajudar a acertar essas funções? Muito obrigado. Compartilhar este post Link para o post Compartilhar em outros sites
Beraldo 864 Denunciar post Postado Dezembro 4, 2008 addslashes() não bloqueia aspas. Ela apenas adiciona barra invertida antes delas. Compartilhar este post Link para o post Compartilhar em outros sites
eibon 2 Denunciar post Postado Dezembro 4, 2008 Para bloquer...pode fazer algo como: <?php //$str = sua string if(preg_match('/(\'|\")/', $str)){ die('\' e \" Não são permitidos!'); } ?> Compartilhar este post Link para o post Compartilhar em outros sites
rvlira 0 Denunciar post Postado Dezembro 4, 2008 Valeu ai pessoal! Só não entendi uma coisa: qual a função de inserir barras invertidas antes das aspas? Quer dizer... não impede o SQL injection... Creio que ajuda apenas contra PHP injection, não é? Porque vai jogar as aspas para dentro da string, não é isso? Uma outra pequena dúvida: Lá na função "anti_injection" tem um preg_replace para remover caracteres especiais. Eu não entendo de expressões regulares. Queria saber como eu poderia modificar a função preg_replace para que remova as aspas duplas e simples de dentro da string. Novamente agradeço pela ajuda. Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Dezembro 4, 2008 nao é isso, impede sim o sql injection inserir uma barra antes, faz com que o select ignore aquele apostrofo Compartilhar este post Link para o post Compartilhar em outros sites
rvlira 0 Denunciar post Postado Dezembro 4, 2008 Enquanto isso estive em uns artigos que encontrei e parece que o addslashes realmente impede, porém, acho que só no MySQL. Porque aqui no Firebird, se ele encontra uma \ antes de um apóstrofe, a barra estará dentro da string delimitada pelo apóstrofe, ou seja, não impedirá o sql injection. Ou estou enganado? t+! Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Dezembro 4, 2008 Ta enganado, firefox nao tem nada haver com o resto é só um navegador o que você tem que ver se você ta com magic_quotes ativado uma dica antes de querer fazer um ant sql injection procure entender do que você esta se protegendo, o que é sql injection, senao você vai ficar só viajando nessas funções Compartilhar este post Link para o post Compartilhar em outros sites
rvlira 0 Denunciar post Postado Dezembro 4, 2008 Não é Firefox não. É o banco de dados Firebird. Eu não uso o MySQL. Apenas para ilustrar meu raciocínio. Se eu tiver: $sql = "SELECT * FROM USUARIOS WHERE LOGIN='".$nome."'"; #Sem nenhuma proteção mesmo E o usuário inputar: ' or 1=1;-- O banco vai retornar todas as linhas da tabela, pois a SQL terá ficado assim: SELECT * FROM USUARIOS WHERE LOGIN='' or 1=1;--' Se eu adicionar addslahes antes de jogar a variável dentro da sql, o comando ficará assim: SELECT * FROM USUARIOS WHERE LOGIN='\' or 1=1;--' Ou seja, continuará trazendo todos os registros da tabela, pois apesar de não haver um usuário com login "\", 1 é igual a 1. t+! Compartilhar este post Link para o post Compartilhar em outros sites
eibon 2 Denunciar post Postado Dezembro 4, 2008 Você está equivocado.Dá uma lida sobre sql-injection... Se você coloca a barra de escape,o que vem depois é interpretado como uma string e não como parte da sua consulta. Abraço! Compartilhar este post Link para o post Compartilhar em outros sites
rvlira 0 Denunciar post Postado Dezembro 4, 2008 Olá novamente. O MySql pode até ignorar o apóstrofe e a aspas quando estão escapadas, mas o firebird e o oracle não o fazem. Fiz o teste em ambos. O mesmo teste que eu coloquei no último post. Por sinal, eu editei que estava errado. Como não uso o MySQL, não tenho como testar nele o exemplo que eu dei, mas posso afirmar que no Firebird e no Oracle não funciona. Só preciso agora descobrir que parâmetros adicionar na função preg_replace para remover da string as aspas simples, duplas e espaços. De mais a mais não creio que seja correto armazenar isso no banco de dados. Principalmente se tratando de login e senha. t+! Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Dezembro 4, 2008 mas nao tem logica isso porque escapando o apostrofo ficaria assim \' or 1=1;-- dai ele vai testar se login = '\' or 1=1;--' , lembre-se você nao ta eliminando o apostrofo do select isso tudo ele vai ler como string e nao executa o "or" eu tenho oracle, sql server, postgresql e mysql aqui na minha maquina mas como falei você primeiro precisa entender o que você tem que proteger e como se ta usando magic_quote, entre outras coisas evitar sql injection é muito simples nao é um bicho de sete cabeças. nao precisa eliminar nenhum caracter para se proteger, basta saber passar um select seguro e os dados por parametros. por exemplo o forum aqui se digita tudo que é caracter e nem por isso se elimina os caracteres e o forum tem select seguro Compartilhar este post Link para o post Compartilhar em outros sites
rvlira 0 Denunciar post Postado Dezembro 5, 2008 Fabyo, você falou exatamente a mesma coisa que eu no post do exemplo. Sim, o apóstrofe do final da SQL é mantido. Mas você está assumindo que deveria funcionar e na verdade não funciona. Vou fundamentar as coisas que eu havia dito até então. Veja o seguinte trecho que extraí de um artigo da internet: Note that using the backslash as an escape character is not standard ANSI SQL. If MySQL is the only database you'll ever use, the backslash may be acceptable, but the same SQL statement run on another database may well fail. Em bom português, ele está dizendo o que eu já tinha dito sem comprovação. A barra invertida como caracter de escape não faz parte do padrão ANSI SQL. A estrutura das consultas SQL do Firebird e Oracle respeitam o padrão, não aceitando a barra invertida como caracter de escape. O MySQL é o único banco em que isso funciona. O artigo ainda informa que no padrão SQL o caracter de escape é o próprio apóstrofe. Ou seja, para escapar um apóstrofe numa string temos que adicionar um outro apóstrofe antes dele. Para consultar o artigo completo, segue o link: http://www.sitepoint.com/article/php-antho...-3-php-mysql/7/ Vale ressaltar ainda que o apóstrofe como caracter de escape é comum em muitas outras linguages além do padrão SQL. Em Object Pascal, por exemplo, se fazemos: varString := '''blablabla'''; //Note que entre a palavra estão três aspas simples seguidas O valor da variável será: 'blablabla' Para o caso de ainda querer confirmar alguma coisa, disponibilizei a seguinte página: http://www.nby.com.br/teste/teste.php É um simples exemplo do que estou falando. Coloque para consultar FULANO (em maiúsculas mesmo). A página retornará apenas o registro do fulano. Agora consulta novamente colocando o seguinte: ' or 1=1-- Pronto! Você verá na tela todos os registros da tabela. E sim, a string passada pelo usuário está sendo escapada com o addslashes. O que acontece é que a SQL ficou assim: SELECT ID, LOGIN FROM USUARIOS WHERE LOGIN='\' or 1=1--' E não sendo a barra invertida o caracter de escape para os bancos que usam o padrão ANSI SQL o resultado é bem óbvio. Segue o código dessa página que confirma tudo o que foi dito: <html><head><title>Teste SQL Injection</title></head><body> <form name="frmteste" action="teste.php" method="post"> Usuário: <input type="text" name="edlogin" size=40><br> <input type="submit" name="btnenviar" value="Enviar consulta"> </form> <?php if (getenv("REQUEST_METHOD")=="POST"){ echo "<br><hr><br>"; #Conecta ao banco de dados $conn = ibase_connect("MEU_HOST","MEU_USER","MINHA_SENHA"); #Pega o nome de usuário consultado já escapando as aspas simples $username = get_magic_quotes_gpc() == 0 ? addslashes($_POST['edlogin']) : $_POST['edlogin']; #Monta a SQL $sql = "SELECT ID, LOGIN FROM USUARIOS WHERE LOGIN='".$username."' ORDER BY LOGIN"; #Executa a consulta $res = ibase_query($conn, $sql); #Exibe os resultados na tela while ($data=ibase_fetch_row($res)){ echo $data[0]."\t".$data[1]."<br>"; } #Fecha a conexão com o banco de dados ibase_close($conn); } ?> </body> </html> Bem, com tudo isso explicado, ainda permaneço com o problema. Como posso fazer para escapar a string usando o apóstrofe em vez da barra invertida? Ou então como ficaria a minha função anti_injection (descrita no post inicial) para que remova as aspas simples, duplas e espaços da string que foi passada no parâmetro? Obrigado. Compartilhar este post Link para o post Compartilhar em outros sites
eibon 2 Denunciar post Postado Dezembro 5, 2008 <?php function removeApostrofe($string){ $string = preg_replace("/(\'|\")/", "", $string); return $string; } $string = "' or '1=1"; $string = removeApostrofe($string); echo $string; //or 1=1 /*foreach($_POST as $key => &$valor){ $_POST[$key] = removeApostrofe($valor); }*/ ?> Abraço! Compartilhar este post Link para o post Compartilhar em outros sites
hinom 5 Denunciar post Postado Dezembro 5, 2008 rvlira o firebird/interbase qeu está usando, qual a versão ? pode ser um bug e talvez seja necessário instalar um patch ou fazer update verifique isso quanto ao SQL injection.. não precisa dar tanta volta basta escapar das aspas simples. Obviamente que isso depende de como vo^ce está montando as querys SQL Compartilhar este post Link para o post Compartilhar em outros sites
rvlira 0 Denunciar post Postado Dezembro 5, 2008 @proust Valeu cara. Só mais uma coisa. Sua função tem o seguinte: preg_replace("/(\'|\")/", "", $string); E lá na função do primeiro post eu tenho: preg_replace("@(--|\#|\*|;|=)@s", "", $txt); Como eu posso transformar essas duas linhas em uma só? Realmente eu não entendo nada de expressões regulares e por isso eu não sei como fazer isso. Creio que se eu criar uma string com as duas expressões concatenadas não vá funcionar, ou não? Ainda não estou na máquina com o php para fazer o teste. @hinom Uso o Firebird 2.1, que é a versão mais atualizada disponível. De qualquer maneira também testei no Oracle. E como consta no post anterior o problema não é do banco não. É porque no padrão ANSI SQL a barra invertida não é caracter de escape. Isso só funciona no MySQL. Novamente agradeço pela ajuda. t+! Compartilhar este post Link para o post Compartilhar em outros sites
hinom 5 Denunciar post Postado Dezembro 5, 2008 Firebird escapes the single-quote (apostrophe) character in strings with another quote character. o Firebird escapa da aspas simples em strings com outra aspa simples referência: http://www.firebirdfaq.org/faq229/ exemplo prático firebird <?php $cant = "can't"; $cant = str_replace("'", "''", $cant); echo "INSERT INTO t1 VALUES('$cant')"; ?> mysql <?php $cant = "can't"; $cant = str_replace("'", "\'", $cant); echo "INSERT INTO t1 VALUES('$cant')"; ?> Compartilhar este post Link para o post Compartilhar em outros sites
rvlira 0 Denunciar post Postado Dezembro 5, 2008 @hinom Sim, isso aí eu sei. No post anterior eu já tinha escrito isso. O artigo ainda informa que no padrão SQL o caracter de escape é o próprio apóstrofe. Ou seja, para escapar um apóstrofe numa string temos que adicionar um outro apóstrofe antes dele. O problema é que no php tem a função addslashes que escapa com a barra invertida, mas funciona apenas para o MySQL. O ideal seria ter uma função addquotes, hehehe... t+! Compartilhar este post Link para o post Compartilhar em outros sites
hinom 5 Denunciar post Postado Dezembro 5, 2008 então é você mesmo que está complicado a coisa.. usa o str_replace ué Compartilhar este post Link para o post Compartilhar em outros sites
Beraldo 864 Denunciar post Postado Dezembro 5, 2008 já que o PHP não tem uma função nativa para isso, crie a sua, com str_replace(), como o hinom disse. http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Dezembro 5, 2008 O problema é que no php tem a função addslashes que escapa com a barra invertida, mas funciona apenas para o MySQL.t+! Funciona com SQL Server tbm só nao posso afirmar com Oracle e nem firebird porque nunca precisei testar sql injection neles :natal_w00t: Compartilhar este post Link para o post Compartilhar em outros sites