-1

I want to make a simple signup form using PHP/MYSQL. However, when I submit the form, it doesn't add the user to the database. Would be glad if someone can find the solution. Here is my HTML:

<form action="signup.php" method="POST">

<label>Pick a username: </label><input type="text" name="username" /> <br>
  <label>Pick a password: </label><input type="password" name="password" /> <br>
  <label>Verify password: </label><input type="password" name="verify_password" /> <br>
  <label>Email address: </label><input type="text" name="email" /> <br>
  <button type="submit">Sign Up</button>

</form>

And signup.php:

<?php
include 'db.php';

$username = $_POST['username'];
$password = $_POST['password'];
$verify_password = $_POST['verify_password'];
$email = $_POST['email'];

 if ($verify_password !== $password) {
    echo "You didn't type your password correctly!";

} else {
    $sql = "INSERT INTO users (username, password, verify_password, email) 
    VALUES ('$username', '$password', '$verify_password', '$email')";

    $rezultat = mysqli_query($link, $sql);

    header("Location: index.php");
}
?>

EDIT: Here is the db.php:

<?php
define ("MYSQL_HOST", "localhost");
define ("MYSQL_USER", "root");
define ("MYSQL_PASS", "");
define ("MYSQL_DBNAME", "registrationTest");

function connect() {
    global $link;

    $link = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DBNAME) or die ("Connection error: " . mysqli_connect_error);
}
?>
AlienHunter 67
  • 55
  • 2
  • 3
  • 6
  • Where is the $link variable being declared? – MCMXCII Feb 01 '17 at 17:32
  • Do you get any errors? Can you confirm the details in db.php are correct? – Tony Hensler Feb 01 '17 at 17:32
  • You really don't want to do inline sql scripts that way. There is a few security issues you may issues with. – ren.rocks Feb 01 '17 at 17:32
  • 4
    Lots of issues here. First of all, the code is wide open to SQL injection, which means there's no telling what the actual SQL query is. Look into prepared statements with query parameters to address that. Second, you're not examining the result of the query. It could be failing, but you don't check for errors. Look at `mysqli_error()`. Additionally, and less related to the issue but still very important, you're *storing user passwords in plain text*. This is a ***very bad thing***. PHP has built-in mechanisms for password handling, use them. Finally, why store the "verify" value at all? – David Feb 01 '17 at 17:33
  • 3
    You are wide open for SQL injection. Since you're using mysqli, take advantage of [prepared statements](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) and [bind_param](http://php.net/manual/en/mysqli-stmt.bind-param.php). Also, take advantage of mysqli_error() to find out why it's not inserting. – aynber Feb 01 '17 at 17:34
  • `include 'db.php';` = mysql_? mysqli_? PDO? other? – Funk Forty Niner Feb 01 '17 at 17:37
  • used as `http://localhost` or `file:///` (hosted)? too many unknowns. – Funk Forty Niner Feb 01 '17 at 17:37
  • @David I'll look into it. Thanks. – AlienHunter 67 Feb 01 '17 at 17:43
  • @Fred -ii- http://localhost. – AlienHunter 67 Feb 01 '17 at 17:43
  • 1
    again; which mysql api is used to connect with and was it successful? – Funk Forty Niner Feb 01 '17 at 17:51
  • What @Fred-ii- means is _Show us the contents of_ `db.php` – RiggsFolly Feb 01 '17 at 17:58
  • @RiggsFolly I left the question when I posted what I thought to be my last comment ;-) *Gone fishing...* bye. – Funk Forty Niner Feb 01 '17 at 18:04
  • @AlienHunter67 I revisited the question; I posted my answer below. Remember to check for errors with PHP's error reporting and `mysqli_error($link)` on the query. – Funk Forty Niner Feb 01 '17 at 19:12
  • Do not save clear passwords! Just using a hash function is not sufficient and just adding a salt does little to improve the security. Instead iterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Use functions such as `PBKDF2` (aka `Rfc2898DeriveBytes`), `password_hash`/`password_verify`, `Bcrypt` and similar functions. The point is to make the attacker spend a lot of time finding passwords by brute force. Protecting your users is important, please use secure password methods. – zaph Feb 01 '17 at 22:33
  • @zaph I'm sure hoping you weren't the one who downvoted us both down there. If so, and if it's because of that we didn't rewrite their entire code, then that was out of line. Like my answer contains: ***Note: I won't repeat what's been said in regards to the security of your code.*** and there's no need for extremism here; IF it's you. – Funk Forty Niner Feb 01 '17 at 23:20
  • @Fred-ii- Do you believe security is important? If so help others create secure code. These answers will be viewed by many developers looking for a secure solution, please consider that. – zaph Feb 02 '17 at 01:00
  • @zaph Nobody taught me to do my homework except teachers in school and this... and I'm afraid you may take this as a great shock; isn't one. They have links/references to go on, let them take the initiative and **learn**. For all we know, this could be homework/sideline project/educational purposes. The manuals/tutorials are already set into place. Don't go telling me to **"create"** secure code, **it's NOT my job.** So, get over it and your extremist thoughts. – Funk Forty Niner Feb 02 '17 at 01:16
  • @zaph I aplaude your consienciousness, but do you really believe that more than 1% of the OP's we inform about secure code pay any attention to our warnings. 99% just want someone to fix their code so thay can move of to payday on friday. – RiggsFolly Feb 02 '17 at 01:28
  • @RiggsFolly Ok, then no warnings and no answers that provide solutions that are not secure. I have considered your message, do we make a difference, perhaps not much but does that mean we should not try, not provide secure solutions? The last thing we need are more solutions provided that are not secure. – zaph Feb 02 '17 at 01:49
  • _The last thing we need are more solutions provided that are not secure_ I cannot disagree with that statement. But thats the job of an employer to ensure they get a decent developer and are prepared to pay the going rate for a good developer. Most of the bad code out there can be put at the door of **they are cheep lets use them** Outsourcing, is a case in point! But thats another discussion completely – RiggsFolly Feb 02 '17 at 01:52
  • How does the comment WRT developers apply to the answers to this question? The answers provide examples of saving clear text passwords, we knew better 30+ years ago. Security, or the lack of it, is a major problem today. – zaph Feb 02 '17 at 02:16

2 Answers2

0

Seeing you added your connection file in an edit:

Your connection file contains a custom function called connect() but you never called it.

function connect() {
    global $link;

    $link = mysqli_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DBNAME) or die ("Connection error: " . mysqli_connect_error);
}

Either you remove:

function connect() {
    global $link;

}

Or call the function inside your script where you would like it to happen.

I.e.:

<?php
include 'db.php';

echo connect();

// ... rest of your code
  • Note: I won't repeat what's been said in regards to the security of your code.

Edit: Nor will I do a total rewrite for a prepared statement and using a safe password hashing function; it's not my job.

  • I "answered" the question, period.

I will however, include references for them to learn and do it themselves:


Change the following to check if the result was successful. If not, return the error if there is one:

else {
    $sql = "INSERT INTO users (username, password, verify_password, email) 
    VALUES ('$username', '$password', '$verify_password', '$email')";

    $rezultat = mysqli_query($link, $sql);

    header("Location: index.php");
}

to:

else {
    $sql = "INSERT INTO users (username, password, verify_password, email) 
    VALUES ('$username', '$password', '$verify_password', '$email')";

    $rezultat = mysqli_query($link, $sql);
}

if($rezultat){

    header("Location: index.php");
    exit;

}else{
    echo "Error: " . mysqli_error($link);
}
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
  • whoever downvoted this, was out of line. I'm not going to rewrite their entire code using prepared statements and password_hash; we have paying day jobs you know. – Funk Forty Niner Feb 01 '17 at 23:23
  • See my response to @Mohammed Akhtar Zuberi. Helping someone with insecure code that will put clients at risk is not acceptable. – zaph Feb 02 '17 at 00:42
  • 1
    @zaph Yeah I saw that. Again; put in your own answer. It seems we're not doing all the work that you seem not wanting to do. – Funk Forty Niner Feb 02 '17 at 01:18
  • I am not a PHP person so I can't really provide a good solution. In another question my answer was down voted because it only provided password security information and not a direct answer to the question. You commented that it was more of a comment so I deleted the answer and added a comment. Your adding the link to `password_hash` is a step in the right direction. – zaph Feb 02 '17 at 01:54
-2

Below is a simplified code that you can even re-use any number of times for any number of projects by just simply editing the database values.

Below should be your db.php file

<?php
    function db_connect () {
        $link = @mysqli_connect ( 'localhost', 'username', 'password', 'table_name' );

        if ( mysqli_connect_errno () )
            die ( 'Failed to connect to server.' );
        return $link;
    }
?>

This file can now be simply called in any .php file. In your case, it is the Signup Script. Before that, below should be your HTML.

<form action="signup.php" method="POST">

<label>Pick a username: </label><input type="text" name="username" /> <br>

//Note that I have added "ID" to Password and Verify Password. This will be used to match the passwords before even submit.  
<label>Pick a password: </label><input type="password" id="password" name="password" /> <br>
  <label>Verify password: </label><input type="password" id="verify_password" name="verify_password" /> <br>
  <label>Email address: </label><input type="text" name="email" /> <br>

//Note that I have added "Name" to the Button. This will be used in the sign-up script for validation. The script is called by onclick where Javascript fucntion is called.
<button name="singup-details" type="submit" onclick="registerFunction()">Sign Up</button>

</form>

It is recommended to match the passwords via Javascript rather than in your PHP signup script. This stops the user from submitting the form in case the passwords don't match.

Below is the Javascript code you can past just before the </body> tag.

<script type="text/javascript">
    //This will set passwordmatch variable on password and verify_password change.
    $('#password, #verify_password').on('keyup', function () {
    if ($('#password').val() == $('#verify_password').val()) {
      $('#message').html('').css('color', 'green');

      passwordmatch = 'yes';
    } else {
      $('#message').html(' Enter the Password again. Both the fields must match.').css('color', 'red');

      passwordmatch = 'no';
    }
});

//If password matches, it will prompt to ensure that if the entries are correct. Or else, will set the focus to Password field.
    function registerFunction() {
        if (passwordmatch == 'yes') {
          if (confirm('You are about to change your password.\nPress OK to proceed.')) return false;

          $( "#userpassword" ).focus();
          $( "#userpassword" ).select();

          event.preventDefault();
        } else {
          alert('Password do not match. Please check and try again.');

          $( "#userpassword" ).focus();
          $( "#userpassword" ).select();

          event.preventDefault();
        }
    }
</script>

Now finally is your signup.php that needs to be changed.

<?php
    session_start();
    ob_start();

    //You can set timezone in order if you plan to store the registration time as well.
    date_default_timezone_set('Asia/Dubai');

    include 'db.php';


    $username = $_POST['useremail'];

    $password = $_POST['password'];

    $email = $_POST['email'];

    //Saving the password directly is not safe. It is better to encrypt it using, at least, SHA1. Below is the way to encrypt the password.
    $password = sha1($_POST['userpassword']);

    //By checking isset $_POST of the singup button of HTML using its name value, we ensure that the user can browse this page only by filling in the Singup form or else will be sent back to the Signup form.
    if (isset($_POST['singup-details'])) {
        //This is the way you can check that if the user exists or not.
        $sql = "SELECT * FROM your_table WHERE email = '" . $email . "'";
        $result = mysqli_query(db_connect(), $sql);

        $num_row = mysqli_num_rows($result);

        if( $num_row >= 1 ) {
            //If username exists, it will take back to the singup form.
            ?>
                <script language="javascript" type="text/javascript">
                    alert('<?php echo $username; ?> already exists in our records.\nTry Again.');
                    window.location = 'your_signup_form.php';
                </script>
            <?php
        }
        else {
            //If username doesn't exist it will save it into the database. Also note that you do not have to save the Verify Password. It is not required at all.
            $sql1 = "INSERT INTO table_name (username, email, password)
            VALUES ('$username', '$email', '$password')";

            $result1 = mysqli_query ( db_connect(), $sql1 );

            ?>
                <script language="javascript" type="text/javascript">
                    alert('Thank you <?php echo $username; ?> for registering.');
                    window.location = 'any_page_you_want.php';
                </script>
            <?php
        }
    }
    else {
        //In case someone tries to access this page directly, this will take him to the singup page instead.
        ?>
        <script language="javascript" type="text/javascript">
            window.location = 'your_signup_form.php';
        </script>
        <?php
    }
?>

Hope this helps. Happy coding...

  • SHA1, indeed all cryptographic hash functions, are not encryption. Further just using a hash even with a salt or HMAC is not secure, for PHP one should use `password_hash` and `password_verify`, they iterate for about 100ms to add security. See the comment to the question about password security. – zaph Feb 01 '17 at 22:37
  • @zaph so what? You want us to do complete rewrites for every question that comes in Stack? If that's your downvote here, and in mine; it's uncalled for and put in your own answer by totally doing a rewrite. We do this for FREE and we do have paying jobs on top of this "hobby". – Funk Forty Niner Feb 01 '17 at 23:23
  • Do you offer a step ladder when requested to help someone jump off a bridge? The security of the OP's clients deserve current best practices. At least provide information in the answer that it is not a secure solution and point out why and a secure option. These answers will be viewed at by many developers looking for a secure solution, please consider that. – zaph Feb 02 '17 at 00:42
  • 1
    _It is recommended to match the passwords via Javascript rather than in your PHP signup script._ **Not if js is turned off** By all measn validate in js but it must also be done in the Server Code as well – RiggsFolly Feb 02 '17 at 01:26
  • Javascript is by default enabled in almost every browser. There are hardly only a few who manually disables it. This number is very low and we all know this. You can even Google to validate this point. Using Javascript as a primary validation option is recommended. Even Facebook does the same in Signup. A backup validation can be added, which can be added to the answer. But it is not fair to say that just because of a few numbers drop the primary option. – Mohammed Akhtar Zuberi Feb 02 '17 at 10:38
  • As far as I know and have used Stackoveflow to learn, I respect the level of question and answers are also supposed to be matching that level. To be honest, communicating directly with the database using your web application is not secure in itself. The secure option is using any service in between and tokens instead of SESSIONS for restricted access. Do you think it is wise to answer this question this way? – Mohammed Akhtar Zuberi Feb 02 '17 at 10:41
  • @RiggsFolly has done the right thing by adding the missing pieces in the answer. Thank you brother! – Mohammed Akhtar Zuberi Feb 02 '17 at 10:44