+2

PHP - Validação de senha simples e segura!

criado por Andrey Box em 22/12/2006 8:06am
Como o form está pronto, agora vamos a parte que interessa, a validação PHP.

<?php
mysql_connect("localhost","root","");
mysql_select_db("test");

/*
   Função do Arquivo: Demonstrar como fazer um sistema de login seguro!
*/

function removerCodigoMalicioso($comSeguranca) {
   $comSeguranca = addslashes($comSeguranca);
   $comSeguranca = htmlspecialchars($comSeguranca);
   $comSeguranca = str_replace("SELECT","",$comSeguranca);
   $comSeguranca = str_replace("FROM","",$comSeguranca);
   $comSeguranca = str_replace("WHERE","",$comSeguranca);
   $comSeguranca = str_replace("INSERT","",$comSeguranca);
   $comSeguranca = str_replace("UPDATE","",$comSeguranca);
   $comSeguranca = str_replace("DELETE","",$comSeguranca);
   $comSeguranca = str_replace("DROP","",$comSeguranca);
   $comSeguranca = str_replace("DATABASE","",$comSeguranca);
     
   return $comSeguranca;
}

if($_POST['logar']) {
  
   $login          = $_POST['login'];
   $senha        = $_POST['senha'];
  
   $login = removerCodigoMalicioso($login);
   $senha = removerCodigoMalicioso($senha);
  
   $sql = "
           SELECT usuarioLogin
           FROM usuario
           WHERE usuarioLogin = '".$login."'
             AND usuarioSenha = '".md5($senha)."'
           ";
          
   $resultado = mysql_query($sql) or die(mysql_error());
  
   if(mysql_num_rows($resultado) == 1) {
      ?>
      <span>Logou no sistema!</span>
      <?php
   }
   else {
      ?>
      Erro ao tentar acessar o sistema, verifique seu LOGIN e SENHA!
     <?php
   }
}
?>

O Código está ai, mas o que ele faz realmente?
Esse código acima, remove todos os tipos de SQL Injection que poderia estar afetando o funcionamento normal do seu sistema de login. Todos os $_POST que são enviados pelo formulário passam pela função que faz a remoção de qualquer código malicioso.

Uma dica interessante seria obrigar o usuário a colocar pelo menos 6 caracteres, não deixar no login e senha repetir no campo "aaaaaa" ou sequencial como "123456" ou "abcdef" e ainda sugerir ao usuário utilizar letras e números ao mesmo tempo.

Quero agradecer ao Google Analytics que está indicando o que os visitantes do meu site querem ler e o que eles mais procuram na net. Resolvi escrever esse POST porque vi que muitos que busca algo pelo Google relacionado ao PHP são iniciantes, e nada melhor do que um sistema de LOGIN seguro, que é o que muita gente falha hoje em dia. Conheço empresas que estão fortes no mercado de software, que não tem essa preocupação, então diria que não seria somente para iniciantes, mas também para pessoas despreocupadas com as informações do PRÓXIMO!

Valeu, espero que gostem do post!

Att.,
Andrey Pedro Lefkum

Comentários:

Mostrando 1 - 8 de 8 comentários
ola! Dei uma lida no codigo e nos comentarios, queria saber se o codigo esta certo ou não, se vai dar algum problema com o usuario, eu sou iniciante e godtaria muito de usar no site q estou desenvolvendo.
22/04/2010 12:36am (~14 anos atrás)

Prezados ANDREY, FELIPE e VICTOR
Como iniciante, estou tentando aprender, mas ainda não tenho suficiente conhecimento para usar o código do Andrey com as adaptações sugeridas pelo Felipe e pelo Victor. Portanto, solicito que republiquem o código devidamente adaptado.
Fraternalmente,
CID PEREIRA
28/01/2009 7:27pm (~15 anos atrás)

Andrey Box disse:
Amigo!

Muito Obrigado! Vivendo e aprendendo, claro que não vou levar isso como uma depreciação do meu trabalho, muito pelo contrário, vou ficar feliz em saber qual seria a melhor maneira!

Att.,
Andrey
22/02/2007 3:56am (~17 anos atrás)

Victor Gondim disse:
Andrey, é otimo se preocupar com a segurança. Antes pecar pelo excesso dela do que pelo desleixo. Mas como você mesmo disse, direcionou esse artigo para iniciantes, por isso queria te expor mais algumas coisas:

1) Como o Felipe falou, as linhas de str_replace nao são necessarias. Mas vou um pouco alem: A htmlspecialchars também nao é necessaria, e a junção da htmlspecialchars e da str_replace deixam o programa errado. Infelizmente, errado, pois se a senha do usuario tiver um aspas, um <, ou tiver escrito SELECT, ela vai ser alterada quando nao deveria e o usuario nao vai se identificar mesmo com a senha certa, voce me compreende?

2) Fora isso, como voce vai cifrar a senha usando o md5 antes de coloca-la na busca do banco de dados, voce NAO deve "limpa-la" com a sua funcao. Isso porque, novamente, se a senha do usuario contiver aspas, ela vai ser alterada sem que devesse ser, e o usuario tera problemas novamente, mesmo usando a senha correta.

3) O uso de addslashes() não é mais recomendado para "limpar" entradas para o MySQL. Devemos usar o mysql_real_escape_string() agora.

É isso. Veja bem, nao estou querendo depreciar seu trabalho, pelo contrario, so queria chamar a atencao para esses detalhes. A segurança é muito importante, mas temos que olhar o codigo como um todo e ver exatamente o que estamos fazendo, ao inves de simplesmente filtrar toda a entrada que o usuario dá como se estivessemos prestes a sermos invadidos se nao o fizermos.

Valeu!!
22/02/2007 12:54am (~17 anos atrás)

realmente chará..
16/01/2007 7:12pm (~17 anos atrás)

parabens, ficou otimo, e bom ter companheiros mandando ver aqui na comunidade. show!
30/12/2006 8:22pm (~17 anos atrás)

Parabéns pela iniciativa Andrey.

Algumas coisas importantes que apreendi com o tempo.

1. BD: Campo user deve ser único (não se pode existir 2 usuários com o mesmo login);

2. Para o controle de SQL injections não é necessário essas linhas:

$comSeguranca = str_replace("SELECT","",$comSeguranca);
$comSeguranca = str_replace("FROM","",$comSeguranca);
$comSeguranca = str_replace("WHERE","",$comSeguranca);
$comSeguranca = str_replace("INSERT","",$comSeguranca);
$comSeguranca = str_replace("UPDATE","",$comSeguranca);
$comSeguranca = str_replace("DELETE","",$comSeguranca);
$comSeguranca = str_replace("DROP","",$comSeguranca);
$comSeguranca = str_replace("DATABASE","",$comSeguranca);

Porque: Vamos supor que tens uma query ("SELECT count(1) FROM users WHERE user = '".$username."' AND password = '".$password." LIMIT 1' ");

Caso o usuário deseje fazer aluguma injection ele tem que conseguir de alguma maneira escapar da aspas simples no local das duas variaveis, com o addslashes ele não vai conseguir de maneira alguma...
27/12/2006 2:54pm (~17 anos atrás)

Parabéns Andrey !!!

Simples e eficaz ! Muito bom.
27/12/2006 2:12pm (~17 anos atrás)

Novo Comentário:

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