0

Good afternoon! Im trying to make registration on my web page and i have an issue - registration is happening, but it can create multiple users with same symbols and also same e-mails and dont giving error when passwords dont match.

Here is form -

    <form action = "register.php" method = "post">
                    Select username:<br>
                    <input type = "text" name = "username"><br>
                    Your e-mail:<br>
                    <input type = "email" name = "email"><br>
                    Set password:<br>
                    <input type = "password" name = "password1"><br>
                    Repeat password:<br>
                    <input type = "password" name = "password2"><br>
                    <button>&nbsp;</button>
                </form>

and here is PHP code -

    <?php



        if (isset($_POST['username']) && isset($_POST['email']) && isset($_POST['password1']) && isset($_POST['password2'])){


            $query = 'select * from users where username = "'.addslashes($_POST['username']).'"';
            $numrows = mysqli_num_rows($link,$query);
            if($numrows == 0){
                    $query_mail = 'select * from users where email = "'.addslashes($_POST['email']).'"';
                    $numrows_mail = mysqli_num_rows($link,$query_mail);
                    if($numrows_mail == 0){
                        if(isset($_POST['password1']) == isset($_POST['password2'])){
                            $sql = 'INSERT INTO users (username,password,email) VALUES("'.addslashes($_POST['username']).'","'.addslashes($_POST['password1']).'","'.addslashes($_POST['email']).'")';

                            $result = mysqli_query($link,$sql) or die(mysqli_error($link));

                    if($result){
                        echo 'Account sucsessfully created! You can now log in.';
                    }else{
                        var_dump($result);
                    }
                }else {
                    echo 'Passwords must match!';
                }
                }else {
                    echo 'E-mail allready registered!';
                }
            }else{
                echo 'Username allready in use!';
            }
        }
    ?>

Can someone explain what is incorrect here?

Karlis Pokkers
  • 224
  • 5
  • 18
  • What do you mean by "*multiple users with same symbols*"? Can you give some examples? And you're not *actually* running the query to check against the emails, you use `mysqli_num_rows($link,$query_mail);` - which should throw you errors. – Qirel Feb 21 '17 at 15:41
  • You should also take note that usage of variables, particularly user-input, directly in the query is unsafe. You should use `mysqli::prepare()` with placeholders on your query instead - the manual holds examples on it, http://php.net/mysqli.prepare – Qirel Feb 21 '17 at 15:42
  • And `if(isset($_POST['password1']) == isset($_POST['password2']))` isn't checking if the passwords match, just if they are both set. – Qirel Feb 21 '17 at 15:43
  • Like i can make multiple users with username - "testuser" . About e-mail - I guess not. – Karlis Pokkers Feb 21 '17 at 15:47
  • Don't store your passwords in plain-text! This is not secure *at all!* PHP has built-in functions which you should use to handle storing of passwords, see the [`password_hash()`](http://php.net/manual/en/function.password-hash.php) function which is a lot more secure! – Qirel Feb 21 '17 at 15:50
  • Same thing goes for usernames as for emails, though - you don't execute the query. – Qirel Feb 21 '17 at 15:50
  • Qirel thanks about your information and about security - i know just work is now on process and security i will add last but anyway thanx. – Karlis Pokkers Feb 21 '17 at 15:56
  • You know, I don't mean to be rude, but that's the worst excuse. I understand you want your code to work, but why bother doing the work twice? If you learn it the right way first, then you don't have to go back and alter your code. Security is a *very* important topic, and shouldn't be "fixed later" or ignored. Food for thought! – Qirel Feb 21 '17 at 15:58
  • Thanx will keep this in mind – Karlis Pokkers Feb 21 '17 at 16:08

2 Answers2

1

I've made some modifications to your code, in order for you to see how to use parameterized queries with placeholders. This is very important security-wise, and you should not "add it later", as it most likely never will get done. The below snippet also properly hashes your password, as that's also very important. Security should never be ignored and always be the first thing you think of when building your application.

<?php 
if (isset($_POST['username'], $_POST['email'], $_POST['password1'], $_POST['password2'])) {
    $errors = array();

    $stmt = $link->prepare("SELECT COUNT(id) FROM users WHERE username=?");
    $stmt->bind_param("s", $_POST['username']);
    $stmt->execute();
    $stmt->bind_result($count_username);
    $stmt->fetch();
    $stmt->close;

    $stmt = $link->prepare("SELECT COUNT(id) FROM users WHERE email=?");
    $stmt->bind_param("s", $_POST['email']);
    $stmt->execute();
    $stmt->bind_result($count_email);
    $stmt->fetch();
    $stmt->close;

    if ($count_username)
        $error[] = "That username already exists";

    if ($count_email)
        $error[] = "That email already exists";

    if ($_POST['password1'] !==$_POST['password2'])
        $errors[] = "Passwords doesn't match";

    if (empty($errors)) {
        $password = password_hash($_POST['password1'], PASSWORD_DEFAULT);

        $stmt = $link->prepare("INSERT INTO users (username, password, email) VALUES (?, ?, ?)");
        $stmt->bind_param("sss", $_POST['username'], $_POST['email'], $password);
        if (!$stmt->execute()) {
            if ($db->errno == 1062) {
                /* Some unique values in the database was attempted inserted, might want to add some error-handling */
            }
        } else {
            /* Execution of query failed, TODO: add error-handling */
        }
        $stmt->close();
    } else {
        foreach ($errors as $e)
            echo $e."\n";
    }
}

Note: With the usage of password_hash(), your password column should be at least of length 255, and when you're verifying logins later, you have to verify it by password_verify() - the manual holds examples on how to do just that.

I recommend you read through these links, as they are highly relevant to a login-system, but dealing with user-input and passwords in general.

Readingmaterial and references

Community
  • 1
  • 1
Qirel
  • 25,449
  • 7
  • 45
  • 62
  • I guess this is OOP PHP? If that, then i am only learning PHP programming and will start OOP soon, so i am not clearly understand all, but i will study your code and provided links now. Hudge thanx! P.S. There is no need for "addslashes" before $_POST ? – Karlis Pokkers Feb 21 '17 at 20:04
  • This is the object-oriented approach of MySQLi, yes. You can also use procedural if you want, the manual of each function shows you how (like `mysqli_prepare($link, "...")` instead of `$link->prepare("..")`) And no, `addslashes()` is a horrible function to use like that, use parameterized queries like above, and you won't have to escape quotes in the query. – Qirel Feb 21 '17 at 20:41
0

When you do this if(isset($_POST['password1']) == isset($_POST['password2'])) you are checking that both exists or both not exists, you must change it for if($_POST['password1'] == $_POST['password2']) if you want to check if password matches.

Nerea
  • 2,107
  • 2
  • 15
  • 14