Using preg_replace invalid password with SHA1

4

I was using preg_replace , to avoid SQL injection:

$senha = preg_replace('/[^[:alpha:]_]/', '',$_POST['senha']);

When comparing the $senha received by POST with the bank password (using SHA1), they are not compatible.

Does anyone suggest a better coding that actually prevents SQL injection?

    
asked by anonymous 16.12.2015 / 16:46

3 answers

2

There is no need to filter the string because it will be converted to a hash. The hash will convert everything, including escape characters that would allow sql injections or any other types of injections.

In short, do not worry about anti-injection filters for that particular case.

See an example test to understand in practice:

$str = '\' delete from users; --\'';
echo sha1($str);

To be clearer, you should be more concerned with validating the received parameter:

$senha = null;
if (isset($_POST['senha']))
    $senha = trim($_POST['senha']);

if (!empty($senha))
    $senha = sha1(trim($_POST['senha']));
else
    echo 'senha não pode ser vazia'; exit;
    
16.12.2015 / 17:24
3

Obviously, the question already has an answer, but to complement that in the comments, "Do not use sha1 to encrypt passwords" , simply because protect.

To address validations, I recommend using the & native validation constants of PHP - PHP Filters - or you can still read

16.12.2015 / 19:48
2

One way to filter sha1 would look like this:

function isSHA1($sha1) {
    return (bool) preg_match('/^[0-9a-f]{40}$/i', $sha1);
}

If you are using PDO for example, you can do this:

$dbh = new PDO("mysql:host=localhost;dbname=seubanco", $user, $pass);  

try {

      if (!isset($_POST['usuario'])) {
          throw new PDOException('Informe o nome de usuário!');
      }
      if (!isset($_POST['senha'])) {
          throw new PDOException('Informe a senha!');
      }

      if (!isUser($_POST['usuario'])) {
          //aqui você cria um método para tratar o usuário
          throw new PDOException('Informa um usuário válido!');
      }

      if (!isSHA1($_POST['senha'])) {
          throw new PDOException('A senha informada é inválida!');
      }

       $stmt = $dbh->prepare("
                            INSERT INTO usuarios (usuario, senha)
                            VALUES (:user,:pass)
                           "); 

       $usuario = $_POST['usuario'];
       $senha = $_POST['senha'];

       $stmt->bindParam(':user', $usuario);
       $stmt->bindParam(':pass', $senha);
       $stmt->execute();

} catch(PDOException $e) {
    echo $e->getMessage();
}

But you do not need to validate sha1 for a case like this, as the user will enter a normal password, and then it will be converted to sha1 :

$dbh = new PDO("mysql:host=localhost;dbname=seubanco", $user, $pass);  

try {

      if (!isset($_POST['usuario'])) {
          throw new PDOException('Informe o nome de usuário!');
      }
      if (!isset($_POST['senha'])) {
          throw new PDOException('Informe a senha!');
      }

      if (!isUser($_POST['usuario'])) {
          //aqui você cria um método para tratar o usuário
          throw new PDOException('Informa um usuário válido!');
      }

       $stmt = $dbh->prepare("
                            INSERT INTO usuarios (usuario, senha)
                            VALUES (:user,:pass)
                           "); 

       $usuario = $_POST['usuario'];
      //convertendo a senha para sha1
       $senha = sha1($_POST['senha']);

       $stmt->bindParam(':user', $usuario);
       $stmt->bindParam(':pass', $senha);
       $stmt->execute();

} catch(PDOException $e) {
    echo $e->getMessage();
}
  

OBS: I do not recommend using hash with sha1() and nor md5() , although they are safe, as long as you include token next to the password, both have collision failure: In this question, talk more about it

A good alternative to password is the password_rash .

    
17.12.2015 / 12:02