18

I already have an advanced user login/register system on my website (colemansystems.psm2.co.uk). However, I would like to have a email sent to new users for verification of their email address. If they have not clicked the link they will not be able to access their account. I am semi-experienced with PHP and MySQL, so please explain in depth.

The code I'm using for the verify.php file (the link the user click on with a GET (for example, verify.php?d=51773199320))

$secret = $_GET['d'];
$result = mysql_query("SELECT valid FROM users WHERE secret=$secret");
while ($row = mysql_fetch_array($result))
{
    $valid = $row['valid'];
}
if ($valid == "") {
    echo"There seems to be a problem with the verification code.<br><br><br><br><br>";
}
elseif ($valid == "1")
{
    echo"Your account is already verified.<br><br><br><br><br>";
}
else
{
    mysql_query("UPDATE users SET valid = '1' WHERE secret=$secret");  
    echo "Thank you, your account is now verified and you are free to use the exclusive features!<br><br><br><br><br><br>";
}

Is this secure?

Braiam
  • 1
  • 11
  • 47
  • 78
ryryan
  • 3,890
  • 13
  • 43
  • 72

3 Answers3

33

The easiest way is not to register unverified users at all.

Ask them for an email address and send email with a link that contains this address sealed with a hash. Upon receiving this link you can start the registration process.

Something like this

$secret = "35onoi2=-7#%g03kl";
$email = urlencode($_POST['email']);
$hash = MD5($_POST['email'].$secret);
$link = "http://example.com/register.php?email=$email&hash=$hash";

And in your register.php add 2 hidden fields to the registration form - email and hash, storing their received values from GET.

Finally, process registration and check,

if (md5($_POST['email'].$secret) == $_POST['hash']) {
    //Continue registration.
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • 1
    this is a smart solution, you dont have to store the verificaton code in your database. – coolkid Sep 26 '10 at 17:12
  • I have taken your information on borad but made php generate a random code, this is then inserted into the database on the same row as the user + the valid field is set to 0 (to not allow them in). When they click on the link it then checks where the code is set to in the database and makes sure it isn't already valid and then sets valid to 1. This then allows them in. I'm not sure if it's secure though. – ryryan Sep 26 '10 at 17:58
  • This is the code i am using on the verify.php (the one that the user click with the secret at the end as a GET) at the top. – ryryan Sep 26 '10 at 18:01
  • Kinda hinges on a risky single point of failure though, no? Anyone gets a hold of that secret can register under any email they like. – Drazen Bjelovuk Aug 11 '17 at 02:16
  • I prefer a randomly-generated code stored in a database, to a hash. Hashes can be cracked, md5 in particular has been broken for years (2008, *before* your answer). It is easier to crack hashes used for email validation because an attacker can gather data by registering multiple accounts with different emails and seeing what hash is generated. If the attack succeeds, an attacker can validate accounts with fake emails. Randomly-generated codes are much more secure, but if you're gonna hash, at least use something stronger like sha256 or better. – cazort Oct 27 '21 at 16:04
2

Easiest for whom - user, coder, computer? What are you optimizing - the quantity of keypresses, the size of the code, the user experience?

The easiest to code is probably unsafe. You should check the email address for correctness before sending a letter to it.

0

after registration create a hashed string and save it to the temporary user table send that hashed string to the user email address using this code

if(isset($_POST['register']))
{
$email_id=$_POST['email'];
$pass=$_POST['password'];
$code=substr(md5(mt_rand()),0,15);
mysql_connect('localhost','root','');
mysql_select_db('sample');

$insert=mysql_query("insert into verify values('','$email','$pass','$code')");
$db_id=mysql_insert_id();

$message = "Your Activation Code is ".$code."";
$to=$email;
$subject="Activation Code For Talkerscode.com";
$from = 'your email';
$body='Your Activation Code is '.$code.' Please Click On This link <a href="verification.php">Verify.php?id='.$db_id.'&code='.$code.'</a>to activate your account.';
$headers = "From:".$from;
mail($to,$subject,$body,$headers);

echo "An Activation Code Is Sent To You Check You Emails";
} 

and after that create a verify page and then

if(isset($_GET['id']) && isset($_GET['code']))
{
$id=$_GET['id'];
$code=$_GET['id'];
mysql_connect('localhost','root','');
mysql_select_db('sample');
$select=mysql_query("select email,password from verify where id='$id' and code='$code'");
if(mysql_num_rows($select)==1)
{
    while($row=mysql_fetch_array($select))
    {
        $email=$row['email'];
        $password=$row['password'];
    }
    $insert_user=mysql_query("insert into verified_user values('','$email','$password')");
    $delete=mysql_query("delete from verify where id='$id' and code='$code'");
 }
}

if you have any problem here is a complete tutorial http://talkerscode.com/webtricks/account-verification-system-through-email-using-php.php

aditya
  • 131
  • 1
  • 3