0

好的,我有此代码可以发送电子邮件帐户验证链接

      $verifyemail = $clean['email'];
      $to = $verifyemail;
      $subject = 'Virtual Pierz Close | Verify Your Account';
      $message = "Thanks for registering with VPC, on clicking the verification link       below, your account will be confirmed, you can then go ahead buy Virtual Properties,   donating £5 each time to the worthwhile charity.

      http://www.cambrianvacation.co.uk/vpc/registered.php?
      email='$verifyemail'&hash='$hash1' ";

    $headers = 'From:noreply@cambrianvacation.co.uk'; // Set from headers  
    mail($to, $subject, $message, $headers);

然后我有这段代码,它试图通过在数据库中设置 active = 1 来激活帐户,这将成为登录时访问控制逻辑的一部分,没有 active = 1,就没有登录,以及其他保护

  if(isset($_GET['email']) && !empty($_GET['email']) AND isset($_GET['hash']) &&    !empty($_GET['hash'])){  
  // Verify data  


  $accountemail = $_GET['email'];
  $accounthash = $_GET['hash'];
   }
    $accountActive = 1;
    $notactive = 0;
    $username = '';
    $password2 = '';
    $username = 'xxxxxxx';
    $password2 = 'xxxxxxx';

    $db1 = new PDO('mysql:host=localhost;dbname=xxxxxxxxxxxxx', $username,   $password2, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

   $db1->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
   $db1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   try{
   $search = $db1->prepare("SELECT email, hash, active FROM users WHERE email = :email     AND hash= :hash AND active = :active");
   $search->bindParam(':email', $accountemail);
   $search->bindParam(':hash', $accounthash);
   $search->bindParam(':active', $notactive);
   $search->execute();
   $colcount = $search->columnCount();

   }catch(PDOException $e) {
  $e->getMessage();
  } 
       print_r($colcount);
       if($colcount === 3){


      //try{
          $update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash AND active = :active");
          $update->bindParam(':active', $accountActive);
          $update->bindParam(':email', $accountemail);
          $update->bindParam(':hash', $accounthash);
          $update->bindParam(':active', $notactive);
          $update->execute();

      //}catch(PDOException $e) {
      // $e->getMessage();
      //} 

但是我无法更新活动列。

我还考虑过使用 GET['email'] 可能会受到语义 url 攻击,但是如果没有匹配的哈希,逻辑不会激活帐户,这是用 crypt() 随机生成的...... ...如果有人能看到代码中的任何安全漏洞,请告诉我......

4

4 回答 4

0

您的新参数未正确绑定,请更改:

$update = $db1->prepare("UPDATE users SET active=? WHERE email=? AND hash=? AND active = ?");

至:

$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");

编辑 - 完整更新代码:

      $update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");
      $update->bindParam(':active', $accountActive);
      $update->bindParam(':email', $accountemail);
      $update->bindParam(':hash', $accounthash);
      $update->execute();
于 2013-02-12T00:13:29.830 回答
0

你能做的,是根本不包括“电子邮件”。

您可以尝试通过执行以下操作生成 url:

$secret = "1032940fdjsjdkf#@$!@#%djsfisd";
$hash = md5($email.$secret);
$url = "http://www.cambrianvacation.co.uk/vpc/registered.php?hash=".$hash;
于 2013-02-12T00:15:24.117 回答
0

真的没有理由在这里进行两个单独的查询。为什么不只使用一个查询来根据哈希和电子邮件更新记录并且活动 = 0?如果修改的行数 = 1,那么你成功了,否则你失败了。您可能并不关心它失败的原因,因为从安全角度来看,向用户指出更新失败的原因(即错误的电子邮件、错误的哈希、已经活跃的用户等)会很糟糕。

话虽如此,您的问题实际上在于您的更新使用?样式绑定,而您正在使用bindParam()样式:param绑定。这将不起作用,因为准备好的语句中不存在这些值。

所以只需使用这一个查询:

UPDATE users SET active = 1 WHERE email = :email AND hash = :hash AND active = 0

显然,如果您认为要更改活动/非活动的值,那么也可以随意使用参数,但我猜您可能希望将其视为仅具有允许值的布尔样式 tinyint 字段0 和 1,所以在那里进行参数化确实没有意义。

于 2013-02-12T00:16:29.420 回答
0

在更新查询中,您使用的是“?” 对于参数,但随后您尝试将它们设置为使用 bindParam() 命名。你应该使用

$update->execute(array($accountActive, $accountemail, $accounthash, $notactive));

或者这样修改更新查询:

$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");
于 2013-02-12T00:17:02.093 回答