PHP mail()中的链接在发送时激活。怎么预防?

时间:2013-11-01 21:03:26

标签: php email query-string

我的网站有一个循序渐进的过程来激活用户帐户的安全性。 为了获得一个帐户,用户必须填写一些表格,然后PHP在db中生成并存储它们的密钥。

然后它会向他们发送一封电子邮件,其中包含指向该过程中下一页的链接,以验证他们是否使用查询字符串密钥。

所以...

php的mail()也会发送一封类似的文本邮件:

click on the link: website.com/page.php?var=crazynumbersandletters

当这封电子邮件发送时,它会激活页面并运行php!当我检查数据库时,在点击链接之前,电子邮件中发送的页面已经处理了密钥。

据我所知,$ _GET变量对此非常糟糕,该网站即将重建,我将采用不同的方式进行激活,但为了我的理智,这是怎么发生的?

为了防止它运行,我现在要求用户通过单击按钮来触发事件。这是因为这是一封普通的短信吗? HTML电子邮件会阻止这种情况吗? (像PHPmailer类)

提前致谢!

注册页面来源:

<?php
$report = "";

//This code runs if the form has been submitted
if (isset($_POST['submit'])) {

    // Connects to the Database
    $dsn      = "xxx";
    $user     = "xxx";
    $password = "xxx";

    $pdo = new PDO($dsn,$user,$password);


    //This makes sure they did not leave any fields blank
    if (!$_POST['email'] | !$_POST['pass'] | !$_POST['pass2'] | !$_POST['first_name'] | !$_POST['last_name'] ) {

        die('You did not complete all of the required fields');

    }

    //assign name vars
    $firstname = ucfirst($_POST['first_name']);
    $lastname  = ucfirst($_POST['last_name']);

    // checks if the email is in use
    $email = $_POST['email'];
    $emailpieces = explode('@', $email);

    if ($emailpieces[1] !== 'domain.com') {

        die('Sorry, that email is invalid.');

    } 

    $sql = "SELECT field2 FROM table WHERE field1 = :field1;";
    $test = $pdo->prepare($sql);
    $test->bindValue(':field1',$email);
    $check = $test->rowCount();

    //if the name exists it gives an error
    if ($check > 0) {

        die('Sorry, but '.$email.' is already in use.');

    }

    $pass1 = $_POST['pass'];
    $pass2 = $_POST['pass2'];
    // this makes sure both passwords entered match
    if ($pass1 !== $pass2) {

        die('Your passwords did not match.');

    }

    // here we encrypt the password
    $pass = md5($pass1);

    //create activation key
    $activation_key = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 25);

    // now we insert it into the database
    $q    = "INSERT INTO table        (field1,field2,field3,field4,field5,field6,field7,field8,field9) ";
    $q   .= "VALUES (:field1,:field2,:field3,:field4,:field5,:field6,:field7,:field8,:field9);";
    $stmt = $pdo->prepare($q);
    $stmt->bindValue(':field1',$firstname);
    $stmt->bindValue(':field2',$lastname);
    $stmt->bindValue(':field3',$pass);
    $stmt->bindValue(':field4','verify');
    $stmt->bindValue(':field5',$email);
    $stmt->bindValue(':field6',$activation_key);
    $stmt->bindValue(':field7','0');
    $stmt->bindValue(':field8','0');
    $stmt->bindValue(':field9','0');
    $stmt->execute();

    $pdo = NULL;

    //email user
    $link     = "http://www.domain.com/dir/otherpage.php?var=" . $activation_key;
    $to       = $email;
    $subject  = "Subject for email";
    $message  = "blah blah blah\r\n\r\n";
    $message .= "Click the following link:\r\n\r\n" . $link . "\r\n\r\n";
    $message .= "blah blah.\r\n\r\n\r\n";
    $headers  = 'From: me@domain.com\r\nReply-To: webmaster@domain.com\r\nX-Mailer: PHP/' . phpversion();

    mail($to, $subject, $message, $headers);

    //display results
    $report  = "<p><b>Thank you! An email has been sent to " . $email . " with an activation key.</b><br /><br />Please check your mail to complete registration.<br /><br />"</p>";

}

?>

验证页面来源:

    <?php
//get querystring info 
$activate = $_GET['var'];

//first message prompts them for action
$message  = "<form action='' method='post'>";
$message .= "<p style='text-align:center;'>Click the <i>Activate</i> button to finish registration</p><br />";
$message .= "<input type='hidden' name='activate' value='" . $activate . "' />";
$message .= "<p style='text-align:center;'><input type='submit' name='submit' value='Activate' /></p>";
$message .= "</form>";

if (isset($_POST['submit'])) {

    //reset message
    $message = "";

    //get post var
    $activation_key = $_POST['activate'];

    //connect to db
    $dsn      = "xxx";
    $user     = "xxx";
    $password = "xxx";

    $pdo = new PDO($dsn,$user,$password);

    //get user info
    $sql = "SELECT field1,field2,field3,field4 FROM table WHERE field5 = :field5;";
    $get = $pdo->prepare($sql);
    $get->bindValue(':field5',$activation_key);
    $get->execute();
    $result = $get->fetch(PDO::FETCH_ASSOC);

    if ($get->rowCount() == 1) {

        //update activation key and set password change key
        $new_activation_key = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 25);
        $password_key        = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 25);
        $q                   = "UPDATE table SET field1 = :field1, field2 = :field2, field3 = :field3 WHERE field4 = :field4;";
        $stmt                = $pdo->prepare($q);
        $stmt->bindValue(':field1',$new_activation_key);
        $stmt->bindValue(':field2',$password_key);
        $stmt->bindValue(':field3','activated');
        $stmt->bindValue(':field4',$activate);
        $stmt->execute();

        //set message
        $message  = "<p style='text-align:center;'>" . $result['firstname'] . " " . $result['lastname'] . ", your account has been activated.<br /><br />";
        $message .= "Please click <a href='http://www.domain.com/dir/anotherpage.php?var=" . $password_key . "'>HERE</a> to set your password.</p>";

    } else {

        //failed - have user email webmaster
        $subject = "Account failed activation";
        $body    = "Account failed to activate for <<enter your email address here>>";

        //set message
        $message = "<p>There was a problem activating your account.<br /><br />Please contact the <a href='mailto:me@domain.com?subject=" . $subject . "&body=" . $body . "'>WebMaster</a> to have your account activated.</p>";

    }

    $pdo = NULL;

}

0 个答案:

没有答案