I have hand-coded a forgotten-password reset system. I am apprehensive about security issues/vulnerabilities. What part of this can be exploited or could be made more secure?
forgot-password.php
<?php
require_once 'connect.php';
if($_SERVER['REQUEST_METHOD'] === 'GET') {
if(isset($_GET['email']) && !empty($_GET['email'])) {
$email = htmlentities(mysqli_real_escape_string($connection, trim($_GET['email'])));
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
$find_email_address_query = "SELECT * from users WHERE email = '{$email}'";
$do_find_email_address_query = mysqli_query($connection, $find_email_address_query);
if($do_find_email_address_query) {
$count_email = mysqli_num_rows($do_find_email_address_query);
if($count_email > 0) {
$hash = sha1(md5(mt_rand(0, 1000000000)));
$forgot_password_hash_query = "UPDATE users SET forgot_password_hash = '{$hash}'
WHERE email = '{$email}'";
$do_forgot_password_hash_query = mysqli_query($connection, $forgot_password_hash_query);
if($do_forgot_password_hash_query) {
$data = array("result" => 1, "message" => "Link To Reset Your Password Has Been Successfully
Sent To $email");
sendEmail($email, $hash);
}
else {
$data = array("result" => -5, "message" => "Error Encountered! Try Again Later.");
}
}
else {
$data = array("result" => -4, "message" => "Non-Existant Email Address! Perhaps You Need To Register
For An Account.");
}
}
else {
$data = array("result" => -3, "message" => "Encountered A Problem Resetting Your Password!
Please Try Again Later.");
}
}
else {
$data = array("result" => -2, "message" => "Invalid Email Address! [email protected] is an example
of the correct format.");
}
}
else {
$data = array("result" => -1, "message" => "No Email Address Provided!");
}
}
else {
$data = array("result" => 0, "message" => "Incorrect Request Method!");
}
function sendEmail ($recipient, $hash) {
$to = $recipient;
$subject = "Reset Your Password | DOMAIN.COM";
$message = '
Did you just forget your password ?
No worries! It is just too easy to get a new one.
Please click this link to reset your password.
http://www.DOMAIN.COM/reset-password.php?email='.$to.'&hash='.$hash.'
'; // Our message above including the link
$headers = 'From:[email protected]' . "\r\n"; // Set from headers
mail($to, $subject, $message, $headers); // Send our email
}
mysqli_close($connection);
/* JSON Response */
header('Content-type: application/json');
echo json_encode($data, JSON_PRETTY_PRINT);
?>
reset-password.php
<?php
require_once 'connect.php';
session_start();
$type_json = true;
if($_SERVER['REQUEST_METHOD'] === 'GET') {
if(isset($_GET['email']) && !empty($_GET['email']) && isset($_GET['hash']) && !empty($_GET['hash'])) {
$email = htmlentities(mysqli_real_escape_string($connection, trim($_GET['email'])));
$hash = htmlentities(mysqli_real_escape_string($connection, trim($_GET['hash'])));
$search_query = "SELECT email, hash, status FROM users WHERE email = '{$email}' AND forgot_password_hash = '{$hash}' AND
status = '1'";
$do_search_query = mysqli_query($connection, $search_query);
if($do_search_query) {
$count_rows = mysqli_num_rows($do_search_query);
if($count_rows > 0) {
$_SESSION['email'] = $email;
$_SESSION['hash'] = $hash;
$type_json = false;
echo "<form method='post' action='do-reset.php'><input type='password' name='password'><br><input type='submit' value='Reset My Password'></form>";
}
else {
$data = array("result" => -3, "message" => "Invalid URL or Perhaps The Password Has Already Been Reset Using This Link!");
}
}
else {
$data = array("result" => -2, "message" => "Something Went Wrong! Try Again Later.");
}
}
else
{
$data = array("result" => -1, "message" => "Certain Request Parameters Are Missing!");
}
}
else {
$data = array("result" => 0, "message" => "Incorrect Request Method!");
}
mysqli_close($connection);
/* JSON Response */
if($type_json) {
header('Content-type: application/json');
echo json_encode($data, JSON_PRETTY_PRINT);
}
?>
update-password.php
<?php
require_once 'connect.php';
session_start();
$type_json = true;
if($_SERVER['REQUEST_METHOD'] === 'GET') {
if(isset($_GET['email']) && !empty($_GET['email']) && isset($_GET['hash']) && !empty($_GET['hash'])) {
$email = htmlentities(mysqli_real_escape_string($connection, trim($_GET['email'])));
$hash = htmlentities(mysqli_real_escape_string($connection, trim($_GET['hash'])));
$search_query = "SELECT email, hash, status FROM users WHERE email = '{$email}' AND forgot_password_hash = '{$hash}' AND
status = '1'";
$do_search_query = mysqli_query($connection, $search_query);
if($do_search_query) {
$count_rows = mysqli_num_rows($do_search_query);
if($count_rows > 0) {
$_SESSION['email'] = $email;
$_SESSION['hash'] = $hash;
$type_json = false;
echo "<form method='post' action='update-password.php'><input type='password' name='password'><br><input type='submit' value='Reset My Password'></form>";
}
else {
$data = array("result" => -3, "message" => "Invalid URL or Perhaps The Password Has Already Been Reset Using This Link!");
}
}
else {
$data = array("result" => -2, "message" => "Something Went Wrong! Try Again Later.");
}
}
else
{
$data = array("result" => -1, "message" => "Certain Request Parameters Are Missing!");
}
}
else {
$data = array("result" => 0, "message" => "Incorrect Request Method!");
}
mysqli_close($connection);
/* JSON Response */
if($type_json) {
header('Content-type: application/json');
echo json_encode($data, JSON_PRETTY_PRINT);
}
?>