Ir para conteúdo

POWERED BY:

Arquivado

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

Micilini Roll

SQL INJECTION,como se cuidar?

Recommended Posts

olha isso:

 

amos analisar o que ocorre quando um usuário tenta se autenticar. Vamos supor que ele é usuário cadastrado com nome Macoratti e senha 123456 (só suposição). Ao informar o nome e a senha e clicar no botão Enviar o script do arquivo login.asp será executado. Vamos ver como ficou a instrução SQL montada neste caso :

 

select count(*) from usuarios where nomeUsuario='macoratti' and senhaUsuario='123456'

 

Neste caso o usuário macoratti, senha 123456 será autenticado e terá acesso ao sistema. Tubo bem ?

 

Não , se você usa este tipo de instrução SQL nada esta bem pois o texto final da consulta SQL depende inteiramente do conteúdo das variáveis , e , se o conteúdo destas variáveis não for validado e tratado o texto final concatenado poderá ser um SQL adulterado através de uma injeção SQL.

 

Quer ver ? Vou começar pegando leve. Vamos supor que um hacker decidiu invadir sua página. Uma das primeiras coisas que ele pode fazer é tentar uma injeção SQL , e, vai começar verificando se você esta tratando o apóstrofe (aspa simples: '). Se você não sabe a presença de um caractere de apóstrofe (') no conteúdo de uma variável concatenada no SQL é usada para delimitar strings de texto. Então suponha que ele digite os seguintes dados nos campos nome e senha:

 

nome = tes'te

senha =

 

Se você não tratar o apóstrofe vai ocorrer um erro de SQL (incorrect Sintax) ,e , vendo isto o hacker vai ficar mais animado...

 

Agora vou pegar pesado. Suponha então que a seguir ele digite os seguintes dados

 

nome = ' ; drop table users--

senha =

 

Este comando irá excluir a tabela users (se ela existir). E se você pensa que é muito difícil o hacker adivinhar o nome da sua tabela vou mostrar mais abaixo que ele pode fazer isto de uma maneira simples. Isto é possível pois o caractere (;) indica o fim de uma consulta e o começo de outra em T-SQL , e , o caractere (--) no final da linha faz com que o scrpt ASP seja executada sem erro.

 

Continuando o ataque , ele pode também informar o seguinte :

 

nome = admin

senha = ' or 1=1--

 

veja como vai ficar a consulta SQL montada:

 

select count(*) from usuarios where nomeUsuario='admin' and senhaUsuario='' or 1=1--'

 

Aqui a consulta irá verificar se o nome do usuário é admin e se senha é vazio ou 1 for igual a 1 ( o que é verdade) ; bingo, se existir um usuário admin ele entrou no seu sistema.

 

Ele pode também tentar o seguinte :

 

nome = ' or 1=1--

senha =

 

a consulta SQL montada será :

 

select count(*) from usuarios where nomeUsuario='' or 1=1 --' and senhaUsuario=''

 

e bingo , ele burlou o seu sistema.

 

O hacker pode também tentar o seguinte :

 

nome = ' OR "='

senha = ' OR "='

 

e a consulta SQL montada será :

 

select count(*) from usuarios where nomeUsuario='' OR "=" AND senhaUsuario='' OR "="

 

a consulta agora esta fazendo a comparação : OR "=" que é sempre verdadeira. Bingo ele entrou no seu site.

 

Para saber o nome das tabelas e campos o hacker pode fazer o seguinte :

 

nome = ' having 1=1--

senha =

 

isto pode causar o seguinte erro:

 

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

 

[Microsoft] [ODBC SQL Server Driver]

 Column 'usuarios.codigo' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.

 

/login.asp , line 28

 

e bingo , o hacker agora sabe que o nome da tabela é usuarios e o nome do campo relacionado no formulário como nome é codigo.

 

E então , o que você acha que ele vai fazer ? Fazer a mesma coisa para o campo senha e então ele vai saber o nome da tabela e dos campos relacionados ao formulário. Imagine o estrago que ele não será capaz de fazer agora...

 

Pensa que ele pode ficar somente nisto. Já conhecendo o nome da tabela e das colunas se o hacker quiser saber o tipo de dados do campo ele pode fazer o seguinte :

 

nome = ' UNION SELECT SUM(nomeUsuario) FROM usuarios--

senha =

 

como o SQL Server vai tentar aplicar a cláusula SUM antes de determinar se o número dos campos nas duas colunas é igual. Ao tentar fazer um SUM em um campo texto o sistema pode emitir a seguinte mensagem de erro:

 

Microsoft OLE DB Provider for ODBC Drivers error '80040e7'

 

[Microsoft] [ODBC SQL Server Driver] [sql Server] The Sum or average aggregate operation cannot take a varchar data type as na argument.

 

/login.asp , line 109

 

e bingo de novo , ele agora sabe o tipo de dado do campo nomeUsuario.

 

Agora sabe o que ele vai fazer ? Vai inserir um usuário com nome senha para se logar , assim :

 

nome = ' ; INSERT INTO usuarios VALUES('hacker','111111')--

senha =

 

e bingo , ele vai se logar como hacker e senha 111111.

 

Acho que com estes exemplos já deu para você perceber que você tem que cuidar com muito mais cuidado das suas instruções SQL .Tenha certeza de uma coisa : as possibilidades do hacker são muitas.

 

e se eu mando uma destas pra cima do meu siteminha!

 

SE A VARIAVEL LOGIN FOR IGUAL OU TIVER ALGUMA PALAVRA RELACIONADA A (' having 1=1--)...( ' OR "=')

 

SENDO $LOGIN É AQUELA QUE ARMAZENA O CAMPO DE TEXTO AONDE A PESSOA DIGITARA SEU LOGIN

PRIMEIRO QUE O CAMPO NAO IRA ACEITAR SIMBOLOS(SOMENTE ACEITARA O PONTO) NEN A SENHA SOMENTE LETRAS E NUMEROS,

 

aplicando isso no meu sistema de login diminue as chançes de um sql injection?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Desenvolva suas aplicações em PDO e não terá problemas, suas perguntas já são obsoletas, um simples javascript já resolve sobre essas senhas fracas e só procurar na net.

Compartilhar este post


Link para o post
Compartilhar em outros sites


PHP
<?	

function anti_injection($sql, $formUse = true)	
{	
// remove palavras que contenham sintaxe sql	
$sql = preg_replace("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/i","",$sql);	
$sql = trim($sql);//limpa espaços vazio	
$sql = strip_tags($sql);//tira tags html e php	
if(!$formUse || !get_magic_quotes_gpc())	
$sql = addslashes($sql);//Adiciona barras invertidas a uma string	
return $sql;	
}	

//modo de usar pegando dados vindos do formulario	
$nome = anti_injection($_POST["nome"]);	
$senha = anti_injection($_POST["senha"]);	

?>

 

olha achei um deste aqui no forum entao como usar,vamos supor que meu projeto tenha 3 formularios em projetos diferentes eu vou terque usar esse comando nos 3 projetos certo?!

 

 

outra coisa eu nao uso $sql para fazer a conecxao com a tabela(select,update,delete...) muitas das vezes eu uso $sql_2,$sql_insert e por ai vai caso eu faço isso eu terei que trocar alguma coisas no codigo acima certo mais o que?

 

vamos supor que no meu projeto o comando $sql_21 esteja fazendo funçao de deletar algo da tabela,ultilizando o codigo acima terei que trocar a variavel $sql por sql_21 ficando assim!

 

$sql_21 = preg_replace("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/i","",$sql_21);

 

é assim!?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça assim, pesquise a fundo como funciona sql injection, mas a fundo mesmo, porque achar que se resume a OR 1 = 1 é praticamente dizer que não sabe nada, assim você vai conseguir analisar os pedaços de script que está envinado e ver as falhas grotescas que eles têm.

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu entrei no site que fala sobre isso,nao é so o OR tem colocar aspas simples no meio do nome tem o drop table,delete tem o having dentre outros,mas e entao você sabe me responder minha pergunta acima? :unsure:

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu entrei no site que fala sobre isso,nao é so o OR tem colocar aspas simples no meio do nome tem o drop table,delete tem o having dentre outros,mas e entao você sabe me responder minha pergunta acima? :unsure:

Sim sei, o que você passou também não resolve, além de criar um grande problema, e se o usuário quiser cadastrar uma das palavras que estão dentro das proibiidas? Ele não vai conseguir? O usuário normal não, mas quem quiser e tiver o mínimo de conhecimento consegue.

 

Sobre essa questão do sql injectiom, pesquise e tire suas próprias conclusões, se você está perguntando se o que você passou resolve ou não você está perdido em um dos pontos (ou nos dois):

1 - Não sabe realmente como funciona sql injection;

2 - Não entende o que os pedaços de script que você copiou fazem.

 

Em ambos os casos se torna perigoso para você mesmo, como disse, use prepared statements, essas "soluções" que você está tentando usar eram ótimos, a uns 5 anos atrás, hoje em dia são totalmente dispensáveis, mas claro, assumir o risco disto ou daquilo vai de acordo com o que cada um pensa.

Compartilhar este post


Link para o post
Compartilhar em outros sites

ok,entao vamos lá um cara ai do forum me sugeriu a ultilizar o pdo que por via das duvidas se torna mais seguro nestas horas certo? outra coisa vi em um site um codigo anti_injection ai esta ele:

 

// Função para evitar SQL Injection nos formulários
function anti_sql_injection($string){
$string = get_magic_quotes_gpc() ? stripslashes($string) : $string;
$string = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($string) : mysql_escape_string($string);
return $string;
}

$nome = anti_sql_injection($_POST['nome']);

 

mas perante o que voce me falou creio que este tambem nao esta moderno ou nao? :huh:

 

que no caso so terei que colocar o anti_sql_injection junto aos campos

 

outra coisa que eu quero compartilhar aqui com voces é o meu sistema de login.php e outro de verifica.php,so que tem um porem tentei quase todos os codigos do sql inejction como OR..HAVING..DROP.... e nada aconteçeu segue ai meus 2 ssistemas:

 

<?
$login = $_POST['login'];
$senha = $_POST['senha'];

include "config.php";

$sql = mysql_query("SELECT * FROM solicitacao WHERE login = '$login'");
$cont = mysql_num_rows($sql);
while($linha = mysql_fetch_array($sql)){
$senha_db = $linha['senha'];
}
if($cont == 0){

echo "
<META HTTP-EQUIV=REFRESH CONTENT='0; URL=login.php'>
<script type=\"text/javascript\">
alert(\"O nome de usuario não corresponde.\");
</script>";

}else{

if($senha_db != $senha){//confere senha

echo "
<META HTTP-EQUIV=REFRESH CONTENT='0; URL=login.php'>
<script type=\"text/javascript\">
alert(\"A senha não corresponde.\");
</script>";

}else{
session_start();
$_SESSION['login_usuario'] = $login;
$_SESSION['senha_usuario'] = $senha;

header('Location: index.php');
}
}
mysql_close($db);
?>

 

----------------------------------------------------------------------

verifica.php

 

<?
session_start();

include "config.php";

if(isset($_SESSION["login_usuario"]) AND isset($_SESSION['senha_usuario'])){

$login_usuario = $_SESSION["login_usuario"];
$senha_usuario = $_SESSION["senha_usuario"];

$sql = mysql_query("SELECT * FROM solicitacao WHERE login = '$login_usuario'");
$cont = mysql_num_rows($sql);
while($linha = mysql_fetch_array($sql)){
$senha_db = $linha['senha'];
}

if($cont == 0){

unset($_SESSION["login_usuario"]);
unset($_SESSION["senha_usuario"]);

echo "
<META HTTP-EQUIV=REFRESH CONTENT='0; URL=login.php'>
<script type=\"text/javascript\">
alert(\"O nome de usuario não corresponde.\");
</script>";

}

if($senha_db != $senha_usuario){//confere senha

unset($_SESSION["login_usuario"]);
unset($_SESSION["senha_usuario"]);

echo "
<META HTTP-EQUIV=REFRESH CONTENT='0; URL=login.php'>
<script type=\"text/javascript\">
alert(\"A senha não corresponde.\");
</script>";

}

}else{

echo "
<META HTTP-EQUIV=REFRESH CONTENT='0; URL=login.php'>
<script type=\"text/javascript\">
alert(\"O usuario e senha não correspondem.\");
</script>";

}

?>

 

este verifica.php esta inserido em todas as paginas,que faz a verificaçao pra ver se o usuario esta logado ou nao!

Compartilhar este post


Link para o post
Compartilhar em outros sites

ok sander sites me ajuda ai,pois bem usar pdo,entao vamos lá se eu for usar pdo isso de sql_injection nao aconteçe certo pois bem,eu ultilizo comandos desse porte para fazer uma conecxao com o banco e dados:

 

config.php

<?
$db = mysql_connect("localhost","root","");
$dados = mysql_select_db("pagina",$db);
?>

 

insert/delete...

$sql = mysql_query("INSERT INTO comunidades_posts (id_user_send, id_comunidade, mensagem, id_adm, titulo, nome) value ('$id_user','$ids','$mens','$id_administrador','$titulo','$nome')");	

 

como ficaria estes codigos usando o pdo,provavelmente o projeto config.php ira sumir certo?! e os do insert into,delete,update..?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara eu ia abrir um tópico sobre isso :pinch: , ai vi o seu. Estou com a mesma dúvida sua :wacko: .

 

Tenho um script aqui, gostaria de saber se isso realmente é valido, por exemplo se posso usar só esta função, ou tenho que complementar com trim(), addslashes(), etc... O que me dizem??

 

Segue o código anti_sql_injetion

//Anti-sql_injection	
function anti_sql_injection($str) {
 if (!is_numeric($str)) {
$str = get_magic_quotes_gpc() ? stripslashes($str) : $str;
$str = function_exists('mysql_real_escape_string') ? mysql_real_escape_string($str) : mysql_escape_string($str);
 }
 return $str;
}

 

Outra coisa, isso não é só para login e senha. Exemplo tenho um site lá (http://www.meusite.com.br/noticia.php?id=01'>http://www.meusite.com.br/noticia.php?id=01) certo?

ai acabei lendo uns assuntos referentes a sql injection e diz que se por aspa simples no final do código exemplo (http://www.meusite.com.br/noticia.php?id=01'>http://www.meusite.com.br/noticia.php?id=01') e aparecer a mensagem de erro de mysql o site está vulnerável a ataques sql injection.

 

O "esquema"/código é o mesmo nesses casos? posso usar essas funções citadas anteriormente para se proteger ?

 

E como eu saberei que meu site está seguro?

 

Obrigado pela atenção.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Já vi em vários lugares falando q o PDO é anti sql injection, por esse motivo utilizo só ele.. e aalguns comandos pabisco com trim entre outros.. para evitar o sql injection. mas não se se ele é realmente 100% anti sql injection.. mas sei q ele é mais seguro e mais rápido xD

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.