私の Web サイトには、セキュリティのためにユーザー アカウントをアクティブ化するための段階的なプロセスがあります。アカウントを取得するには、ユーザーがいくつかのフォームに記入する必要があります。その後、PHP がそれらのキーを生成してデータベースに保存します。
次に、プロセスの次のページへのリンクが記載された電子メールを送信し、クエリ文字列キーを使用して本人であることを確認します。
それで...
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;
}