0

Anti SQL Injection - Solução Global

criado por Otávio Campos de Abreu Serra em 05/07/2010 4:06pm
Procurando na rede métodos de prevenção de SQL Injection, encontrei várias metodologias muito úteis, algumas eficientes, outras braçais, mas, em todas, infelizmente, o maior problema que vi foi que todos os métodos são de nível de aplicação em casos pontuais, e não globais. Ou seja, para previnir SQL Injection, nesses casos, você é obrigado a literalmente modificar toda a sua aplicação, isto é, todos os seus scripts, funções, classes, etc para funcionar conforme essas metodologias, inclusive nas postadas nesse fórum. Por isso, busquei alternativas e cheguei numa solução global. E sendo assim, qualquer sistema que fiz até hoje fica seguro com essa alternativa, basta apenas garantir que ela seja executada.

Pelo que pude verificar, todos os ataques são feitos através do uso das variáveis superglobais de transmissão de dados da máquina cliente para a máquina servidora. Em boa linguagem técnica, estamos falandos das variáveis $_REQUEST, $_POST, $_GET, $_COOKIE e $_FILES que armazenam temporariamente esses dados transmitidos, e é através delas que fazemos a sua recuperação. Como essas variáveis são simplismente Arrays de dados, por que não aplicarmos um pré-processamento neles antes de usar os dados. Além disso, como o que faz com que esse ataque seje possível é o uso inadequado do (') é necessário aplicar uma metodologia addslashes. Portanto, foi baseado nessa lógica que montei o algorítmo a seguir.

function phpAntiSqlInjection($debug = false){
	if($_REQUEST)
	foreach($_REQUEST as $key => $value){
		$_REQUEST[$key] = addslashes($value);
		if($debug) echo "REQUEST: ".$key . " " . $value . "<br />";
	}
	
	if($_POST)
	foreach($_POST as $key => $value){
		$_POST[$key] = addslashes($value);
		if($debug) echo "_POST: ".$key . " " . $value . "<br />";
	}
	
	if($_COOKIE)
	foreach($_COOKIE as $key => $value){
		$_COOKIE[$key] = addslashes($value);
		if($debug) echo "_COOKIE: ".$key . " " . $value . "<br />";
	}
	
	if($_GET)
	foreach($_GET as $key => $value){
		$_GET[$key] = addslashes($value);
		if($debug) echo "_GET: ".$key . " " . $value . "<br />";
	}
	
	if($_FILES)
	foreach($_FILES as $key => $value){
		if($value['name']){
			$_FILES[$key]['name'] = addslashes($value['name']);
			if($debug) echo $key . " " . $value['name'] . "<br />";
		}
	}
	
	return true;
}

Para utiliza-lo é necessário apenas executar essa função antes de qualquer acesso a qualquer variável de transmissão de dados. Isso garante que os dados NÃO serão atacados em qualquer lugar por SQL Injection.

Por último, dependendo do charset do banco de dados é necessário que seja aplicado a operação inversa do addslashes para retirar as barras invertidas. Para isso, é só aplicar stripslashes nos dados acessados via SELECT. Eu apliquei essa metodologia nas funções que tenho pronta para acesso a banco, ou seja, só precisei mudar uma função, pois todos os meus scripts usam a mesma função para fazer SELECT em banco. Segue:

$sql = "SELECT * FROM tabela";
$res = mysql_query($sql);
$max = mysql_num_rows($res);

for($i=0;$i<$max;$i++){
	$rows_aux = mysql_fetch_array($res);
	
	if($rows_aux)
	foreach($rows_aux as $key => $value){
		$rows_aux[$key] = ( !is_numeric($value) ? stripslashes($value) : $value);
	}
	$rows[] = $rows_aux;
}

Espero ter ajudado.

Comentários:

Mostrando 1 - 3 de 3 comentários
Rapaz,
Dá uma olhada nisso aqui: PDO - http://php.net/pdo
19/01/2011 11:01am (~6 anos atrás)

Executa a função phpAntiSqlInjection() em primeiro lugar em todos os arquivos PHPs que você tem. Sempre que houver sql injection, essa função previnirá.

Exemplo seu arquivo php:

<?php

...(seu código)...

?>

Você modifica ele e faz assim:

<?php

function phpAntiSqlInjection($debug = false){
        if($_REQUEST)
        foreach($_REQUEST as $key => $value){
                $_REQUEST[$key] = addslashes($value);
                if($debug) echo "REQUEST: ".$key . " " . $value . "<br />";
        }
        
        if($_POST)
        foreach($_POST as $key => $value){
                $_POST[$key] = addslashes($value);
                if($debug) echo "_POST: ".$key . " " . $value . "<br />";
        }
        
        if($_COOKIE)
        foreach($_COOKIE as $key => $value){
                $_COOKIE[$key] = addslashes($value);
                if($debug) echo "_COOKIE: ".$key . " " . $value . "<br />";
        }
        
        if($_GET)
        foreach($_GET as $key => $value){
                $_GET[$key] = addslashes($value);
                if($debug) echo "_GET: ".$key . " " . $value . "<br />";
        }
        
        if($_FILES)
        foreach($_FILES as $key => $value){
                if($value['name']){
                        $_FILES[$key]['name'] = addslashes($value['name']);
                        if($debug) echo $key . " " . $value['name'] . "<br />";
                }
        }
        
        return true;
}

phpAntiSqlInjection();

...(seu código)...

?>

01/11/2010 11:57am (~6 anos atrás)

sergio disse:
Legal, a pergunta é
Como eu faço exatamente para implantar isto? estou tendo problemas de sql injection e não conheço PHP.
Coloco este código nos posts? crio um documento? insiro em algum arquivo>? rodo no servidor?

Desculpem, é que não sei mesmo.
31/10/2010 11:41am (~6 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)