Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

jcalebe

[Resolvido] Como evitar SQL Injection?

Recommended Posts

Olá!

Como eu posso filtrar os dados recebidos por GET de um Form para evitar o SQL injection?

Uso o MySQL.

 

<?php
//Recebe os dados
$q = $_GET['q'];

//Consulta
$sql = "SELECT * FROM `data` WHERE (`texto` LIKE '%".$q."%')";

$query = mysql_query($sql);
?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

cara, em todos os meus projetos, tenho usado o seguinte:

 

$q = getGet('q');

no lugar do:

$q = $_GET['q'];

 

entendeu ?

tudo oque vier via GET ou POST, passa pelo getGet() ou getPost(), que é do tipo:

function getGet( $key ){
 return isset( $_GET[ $key ] ) ? filter( $_GET[ $key ] ) : null;
} 

 

assim, não tenho os warnings, pois só uso o REQUEST, se ele existir.

E caso exista, todos ainda passam por uma função filter()

 

agora, ponto importante a comentar:

 

mysql_query() sends a unique query (multiple queries are not supported)

http://br.php.net/mysql_query

Compartilhar este post


Link para o post
Compartilhar em outros sites

Uma função bem simples do PHP é muito útil neste caso: addslashes. Um exemplo dela abaixo:

 

$q = addslashes($_GET['q']);

 

Você pode usar também uma outra função chamada: strip_tags

Com esta função você evita também HTML Injection.

 

$q = strip_tags($_GET['q']);

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, da uma olhada.

http://forum.imasters.com.br/index.php?/topic/276729-seguranca-em-php/page__view__findpost__p__1641577

 

Acredito que a mesclagem dessa função com a que o William Bruno passo deve ser excelente.

 

function anti_injection($str){
   // verifica se o valor da string é somente numérico 
   if (!is_numeric($str)) { 
       //verifica se o magic_quotes está habilitado, se sim tira o escape da string, caso não mantem o valor digitado.
      $str = get_magic_quotes_gpc() ? stripslashes($str) : $str;  
      // verifica se a função mysql_real_escape_string está habilitada, se sim roda ela, se não usa o mysql_escape_string
      $str = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($str) : mysql_escape_string($str);
   }

   // retorna o valor tratado 
   return $str;

}

function getGet( $key ){
 return isset( $_GET[ $key ] ) ? anti_injection( $_GET[ $key ] ) : null;
} 

$q = getGet('q');

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá!

 

Agradeço a todos, mas qual destas funções avisaria na tela uma mensagem dizendo que e pessoa fez uma tentativa de SQL/HTML injection?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Nenhuma das anteriores.

 

pq ai você precisa definir qual é a lógica para decidir 'se foi uma tentativa' ou não.

não entendi pq você precisa 'de uma mensagem dizendo que foi uma tentativa de injection', e nem oque isso tem a ver com a dúvida do inicio post.

Compartilhar este post


Link para o post
Compartilhar em outros sites

..., e nem oque isso tem a ver com a dúvida do inicio post.

 

Foi só uma curiosidade passageira.

 

Eu posso juntar todas essas funções sem o risco de uma anular ou "quebrar" a outra?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Poderia ser criada uma ótima classe Anti Injection juntando estes códigos, alguém se habilita? :lol:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Uma forma de fazer isso automaticamente é usando esses foreach.

 

foreach ($_POST as $campo => $valor) {  $$campo = anti_injection($valor); }
foreach ($_GET  as $campo => $valor) {  $$campo = anti_injection($valor); }

 

Já usei muito dessa forma, dessa maneira a variável já vem nomeada e tratada.

 

Não precisa declarar

$nome = $_POST['nome'];

 

Ele já pega o valor do indice do array (nesse caso 'nome') e cria uma variável já tratada com este nome.

 

Então é só chamar.

$nome

 

 

Mas depois de muito tempo preferi utilizar arrays para separar melhor as variaveis.

 

Para quem preferir assim como eu pode tentar utilizando esta forma.

foreach ($_POST as $campo => $valor) { $_POST[$campo] = anti_injection($valor);	 }
foreach ($_GET  as $campo => $valor) { $_GET[$campo] = anti_injection($valor);	 }

 

Não testei mas deve funcionar.

 

Utilizando desta forma basta fazer isto:

// FUNÇÃO ANTI INJECTION
function anti_injection($str){
   // verifica se o valor da string é somente numérico 
   if (!is_numeric($str)) { 
       //verifica se o magic_quotes está habilitado, se sim tira o escape da string, caso não mantem o valor digitado.
      $str = get_magic_quotes_gpc() ? stripslashes($str) : $str;  
      // verifica se a função mysql_real_escape_string está habilitada, se sim roda ela, se não usa o mysql_escape_string
      $str = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($str) : mysql_escape_string($str);
   }

   // retorna o valor tratado 
   return $str;

}


$_POST['Nome'] // Variavel não tratada
$_GET['q'] // Variavel não tratada


// PEGA O VALOR DE $_POST e $_GET e trata.
foreach ($_POST as $campo => $valor) { $_POST[$campo] = anti_injection($valor);	}
foreach ($_GET  as $campo => $valor) { $_GET[$campo] = anti_injection($valor);	}


$_POST['Nome'] // Variavel tratada
$_GET['q'] // Variavel tratada

Compartilhar este post


Link para o post
Compartilhar em outros sites

Interessante este modo Nícolas, pode ser útil para por exemplo quando se tem um formulário, e não se sabe quais os dados que o cliente pode adicionar futuramente, então basta dar um foreach e aplica as váriaveis. Vou estudar isto, pois estou fazendo um formulário de contato e estou procurando a forma mais prática para o usuário final adicionar novos campos sem ter que recorrer a edição do arquivo principal de envio.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá!

Obrigado a todos por me ajudarem nesta questão de segurança.

 

Nícolas, esse script que você postou, juntando todos os outros é muito interessante.

 

Acredito que ele vai ajudar muitas pessoas a se livrarem desse problema por muito tempo, ou até descobrirem uma maneira de burlá-lo.

 

Então, fica aqui para quem precisar, com algumas alterações:

 

//anti injection
function anti_injection($str){
// verifica se o valor da string é somente numérico 
if (!is_numeric($str)) { 
//verifica se o magic_quotes está habilitado, se sim tira o escape da string, caso não mantem o valor digitado.
$str = get_magic_quotes_gpc() ? stripslashes(strip_tags($str)) : $str;
// verifica se a função mysql_real_escape_string está habilitada, se sim roda ela, se não usa o mysql_escape_string	
$str = function_exists('mysql_real_escape_string') ? mysql_real_escape_string($str) : mysql_escape_string($str);
}
//retorna o valor
return $str;
}
//Faz busca por variáveis GET e POST e retorna como "$nome_da_variavel"
foreach ($_POST as $campo => $valor) {  $$campo = anti_injection($valor); }
foreach ($_GET  as $campo => $valor) {  $$campo = anti_injection($valor); }


//Procura por rastros de SQL e HTML Injection
if ((@preg_match('/\\\/', $q)) || (@preg_match('/</', $q))){
exit('Houve um erro na sua consulta.');
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.