baguio loko baguio loko  • 23.10.11 13:14

Entendendo e Consertando o SQL Injection Empty Entendendo e Consertando o SQL Injection 23.10.11 13:14

Entendendo o SQL Injection


Olá a todos, explicarei o que é SQL Injection e demonstrarei algumas técnicas para evita-lo.

Mas o que é SQL Injection?

SQL Injection é uma técnica usada por hackers (crackers) para executar comandos SQL não autorizados e assim obter vantagem de aplicações que utilizam queries SQL dinâmicas.

Exemplo:
Considere a seguinte query:


Código PHP:




<?php

mysql_connect
('localhost', 'user', 'pass') OR die(mysql_error());


$query = "SELECT * FROM users WHERE user='".$_POST['username']."' AND password='".$_POST['password']."'";

mysql_query($query);

?>






Ela pode ser usada para autenticar um usuário, como em um login.
Nós não verificamos os dados enviados pelo usuário, $_POST['username'] e $_POST['password'], sendo assim ele pode enviar qualquer coisa, por exemplo:


Código PHP:




$_POST['username'] = 'admin';

$_POST['password'] = "' OR ''='";








A query ficará assim:


Código:

SELECT * FROM users WHERE user='admin' AND password=' ' OR ' '=' '

Ela permite que qualquer um faça o login sem uma senha válida.

Exemplo 2:
O SQL Injection pode ser bem mais perigoso como o seguinte exemplo.


Código PHP:




<?php

mysql_connect
('localhost', 'user', 'pass') OR die(mysql_error());

$query = "SELECT * FROM users WHERE name = '".$_POST['name']."'";

mysql_query($query);

?>






Um usuário poderá enviar para nossa query o seguinte código:

Código PHP:




$_POST['name'] = "a';DROP TABLE users";








e ela ficará assim:


Código:

SELECT * FROM users WHERE name = 'a'; DROP TABLE users

Ela selecionará o usuário com nome igual a 'a' e logo após irá apagar nossa tabela 'users'.

Como Evitar o SQL injection

Para evitar é necessário que sempre sejam
validados os dados enviados pelo usuário. O PHP nos fornece uma função
para tratar este problema. É a mysql_real_escape_string()


Exemplo:
Podemos solucionar o SQL Injection do primeiro exemplo da seguinte maneira:


Código PHP:




<?php

mysql_connect
('localhost', 'user', 'pass') OR die(mysql_error());


$user = mysql_real_escape_string($_POST['username']);

$pass = mysql_real_escape_string($_POST['password']);


$query = "SELECT * FROM users WHERE user='$user' AND password='$pass' ";


mysql_query($query);

?>






A query ficará assim:


Código:

SELECT * FROM users WHERE user='admin' AND password=' ' OR ' '=' ''


e elá não permitirá mais que qualquer um faça o login sem possuir uma senha válida.


A melhor função para proteger seus sistemas em PHP e MySQL contra SQL Injection é a mysql_real_escape_string(),
ela escapa os caracteres especiais como aspas simples e duplas antes de
enviar para o banco de dados. Porém esta função não funciona em todas
as versões do PHP, então na função que iremos criar temos quer
verificar se ela existe, e caso não exista vamos utilizar a função mysql_escape_string().

Também devemos ter em mente que se a diretiva get_magic_quotes_gpc()
estiver ON ele irá acrescentar barras invertidas automaticamente antes
de aspas simples e duplas, o problema é que ele irá enviar para o banco
de dados com as barras invertidas, estragando o texto. Para contornar
isso basta usar a função stripslashes() para remover essas barras invertidas.

Então vamos montar a nossa função com o nome de anti_sql_injection():



Código PHP:




1 function anti_sql_injection($str) {

2 if (!is_numeric($str)) {

3 $str = get_magic_quotes_gpc() ? stripslashes($str) : $str;

4 $str = function_exists('mysql_real_escape_string') ? mysql_real_escape_string($str) : mysql_escape_string($str);

5 }

6 return $str;

7 }









Note que em nossa função primeiro verificamos se a o valor informado
não é numérico, ou seja, que precisa ser tratado, em seguida
verificamos se a diretiva get_magic_quotes_gpc() está ativada, se estiver usamos a função stripslashes(). Em seguida verificamos se existe a função mysql_real_escape_string(), se existir usamos ela, caso contrário usamos a função mysql_escape_string().

Veja um exemplo de como usar a função:


Código PHP:




01 if ($_SERVER['REQUEST_METHOD'] == 'POST') {

02 $usuario = trim($_POST['usuario']);

03 $senha = trim($_POST['senha']);

04

05 $sql
= 'SELECT COUNT(id_usuario) ';

06 $sql .= 'FROM usuarios ';

07 $sql .= 'WHERE usuario = '' . anti_sql_injection($usuario) . '' ';

08 $sql .= 'AND senha = '' . anti_sql_injection($senha) . '' ';

09

10 $query
= mysql_query($sql) or die('Erro na consulta: ' . mysql_error());

11 $total = mysql_result($query, 0);

12 if ($total > 0) {

13 echo 'Usuário e senha corretos.';

14 } else {

15 echo 'Usuário e/ou senha inválidos.';

16 }

17 }








Pronto! Estamos vacinados contra ataques de SQL Injection, e o melhor de tudo, sem destruir o conteúdo dos nossos sistemas.

Milani Milani  • 06.11.11 11:11

Entendendo e Consertando o SQL Injection Empty Re: Entendendo e Consertando o SQL Injection 06.11.11 11:11

Topico fechadao por inatividade !!!
Permissões neste sub-fórum
Não podes responder a tópicos

BH Servers

Recomendamos a BH Servers com proteção DDOS gratuita em Cloud Server de alta performance. Entrega imediata.