How to stop a user from entering same username and password into the database

#1

I am trying to create a basic login system. So far I have is a user able to signup. I am using the prepared statement and pdo method. This is the function where I am handling the signups. The where not exists clause is not working. It is giving me an error. Any help will be huge. Thanks in advance. Here is the code I have so far:

<?php
require_once('config.php');
// Should return a PDO
function db_connect() {
  
  try {
    // TODO
    // try to open database connection using constants set in config.php
    // return $pdo;
    $servername = DBHOST;
    $databasename = DBNAME;
    $user = DBUSER;
    $password = DBPASS;

    $connectionString = "mysql:host=$servername;dbname=$databasename;";
    $pdo = new PDO($connectionString,$user,$password);
    $pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    return $pdo;
  }
  catch (PDOException $e)
  {
    die($e->getMessage());
  }
}

// Handle form submission
function signup() {
  global $pdo;

  if($_SERVER["REQUEST_METHOD"] == "POST")
  {
    // TODO
    // Prepare the submitted form data and insert it to the database
    $username = $_POST['user'];
    $userpass = $_POST['pass'];
   
  
    $statement = $pdo->prepare("INSERT INTO signup(username,password) VALUES(':user',':pass')
      SELECT * FROM signup WHERE NOT EXISTS (SELECT * FROM signup WHERE username='$username' AND password='$userpass')
LIMIT 1;
      ");
    $statement->bindValue(':user',$username);
    $statement->bindValue(':pass',$userpass);
    $statement->execute();
    

    echo "<script type='text/javascript'>";
    echo "alert('Signup successful')";
    echo "</script>";
  }
}
#2

You should only care that the username is unique. To do this, define the username column as a unique index, just attempt to insert the data, then detect if the query produced a unique index error number.

Also, you should be using password_hash() to hash the passwords, which will give a different hash for the same password, due to the random salt used, so you won’t ever know any of the characteristics of any of the passwords.

2 Likes
#3

What he said…

1 Like
#4

Thank You :slight_smile:

#5

Like they are saying never check a user password when someone else is registering.

I’d do an SQL select first checking username (or email) and if count = 0 then allow the register and if =1 give a message saying pick an other username.

#6

No, No, No! You will build in a race condition and a security problem. @phdr gave the correct answer.

#7

There is no one right way, the guy is asking how to do something there is always more then one way, you’re not creating a race If it’s within a if. What would it be racing… it’s a if statement

But ya should just change it to if executed without creating more then one sql connection and then throw the error in it.

#8

In this case, yes there is. Since you have to ask “What would it be racing” take a minute and learn what a race condition is. While your at it learn about the “Username Enumeration Attack” you are telling the OP to build in.

#9

You’re feeding mixed signals, how would you create a “username is unique” without letting the registering user know that its taken ??

I’m guessing hes smart enuff to block the IPs of people guessing passwords. Like you’r link says to do.

#10

The following are the cases where using a select query followed by an insert query can result in duplicate data being inserted -

  1. The rare case of random concurrent users submitting the same value.
  2. The same user submitting the same value multiple times due to browser/connection/server operational problems.
  3. Hackers submitting rapid-fire requests when trying to trigger errors (for those coders who are still unconditionally outputting the raw database error information onto a live web site.)

Since your database must enforce uniqueness in its design and your code must detect and handle duplicate key errors after the insert has been executed anyway, the select query is unnecessary. It’s just doubling the database server resources used by the operation without providing any benefit.

2 Likes