I've created a register and email verification system on my website. The process is as follows:
User submits email and password
Verification link is emailed
User info is swapped from unverified to verified DB if link is visited
However, I've noticed an interesting "bug" if you'd even call it that.
If I simply open the email in Hotmail without even visiting the link, somehow the user info is swapped from unverified to verified as if the link was clicked.
I'm baffled...
How is this so? Why would this be occurring?
You can try it for yourself by visiting http://www.pillar.fyi/redflagreviews/signinup.php/
By default, the slider is in the "register" position, whereas the other position is for logging in.
PHP (it's messy, forgive me)
<?php
session_start();
session_regenerate_id();
if ($_SESSION["session"])
{
echo "<script type='text/javascript'> location.href = 'http://www.pillar.fyi/redflagreviews/index.php' </script>";
}
else
{
if (!empty($_SERVER["QUERY_STRING"])) # ... && regex to filter out junk
{
parse_str($_SERVER["QUERY_STRING"]);
include "include/connect.php";
# compare token
$statement = $connect->prepare("SELECT entry_time, account_email, account_password, token FROM users_unverified WHERE account_email = :account_email");
$statement->bindParam(":account_email", $email);
$statement->execute();
$result = $statement->fetch(PDO::FETCH_ASSOC);
if ($result["token"]
&& $result["token"] === $token
&& $result["entry_time"] > time() - 600) # token matches
{
# move info to users_verified
$statement = $connect->prepare("INSERT INTO users_verified (account_email, account_password, joined) VALUES (:account_email, :account_password, :joined)");
$statement->bindParam(":account_email", $result["account_email"]);
$statement->bindParam(":account_password", $result["account_password"]);
$statement->execute(array(
":account_email" => $result["account_email"],
":account_password" => $result["account_password"],
":joined" => date("Y-m-d")
));
# delete old entry
$statement = $connect->prepare("DELETE FROM users_unverified WHERE account_email = :account_email");
$statement->bindParam(":account_email", $email);
$statement->execute();
# now redirect to login screen (or update message)
echo "Your email address has been verified and is now active. Sign in below to begin sharing!";
$connection = null; # may be useless
}
else # being hacked or token has expired
{
if ($result["token"]) { echo 'true'.'<br><br>'; }
else { echo '1. false -- $result["token"] -- '.$result["token"].'<br><br>'; }
if ($result["token"] === $token) { echo 'true'.'<br><br>'; }
else { '2. false -- $result["token"] === $token -- ' . $result["token"]. ' === ' .$token.'<br><br>'; }
if ($result["entry_time"] > time() - 600) { echo 'true'.'<br><br>'; }
else { '3. false -- $result["entry_time"] > time() - 600 -- '. $result["entry_time"] . ' > ' . time() - 600 .'<br><br>'; }
echo "Your verification code has expired. Would you like us to send you a new verification link?";
# if yes, then... (add num_id? to SELECT query above)
#####################################################
#####################################################
}
}
else # might cause issues as ELSE
{
if ($_SERVER["QUERY_STRING"]) echo $_SERVER["QUERY_STRING"];
else echo 'query string is false<br><br>';
if ($_SERVER["REQUEST_METHOD"] === "POST")
{
include "include/connect.php";
if ($_POST["action"] === "0") # register
{
######################################
### ###
### prohibit certain domains ###
### such as spamgourmet.org ###
### ###
######################################
$statement = $connect->prepare("SELECT account_email FROM users_verified WHERE account_email = :account_email");
$statement->bindParam(":account_email", $_POST["email"]);
$statement->execute();
$result = $statement->fetch(PDO::FETCH_ASSOC);
if ($result["account_email"]) # email already in use
{
echo "The email account " . $result['account_email'] . " has been registered already.";
}
else # new account, unknown email address
{
# first, check users_unverified to see if verification process is active
$statement = $connect->prepare("SELECT entry_time FROM users_unverified WHERE account_email = :account_email");
$statement->bindParam(":account_email", $_POST["email"]);
$statement->execute();
$result = $statement->fetch(PDO::FETCH_ASSOC);
if ($result["entry_time"]
&& $result["entry_time"] > time() - 600) # verification process is already active
{
echo "Your account is awaiting verification. The verification code will remain active for another "."###"." Would you like us to resend the verification code?";
}
else # initiate the verification process
{
# delete old entry
$statement = $connect->prepare("DELETE FROM users_unverified WHERE account_email = :account_email");
$statement->bindParam(":account_email", $_POST["email"]);
$statement->execute();
# send verification code
echo "An email with a verification link has been sent to your email address. Please verify your ownership of the email account by clicking the link in that email. The verification code will expire in 10 minutes!";
$password = password_hash($_POST["password"], PASSWORD_DEFAULT);
$token = md5($password, FALSE);
$statement = $connect->prepare("INSERT INTO users_unverified (entry_time, account_email, account_password, token) VALUES (:entry_time, :account_email, :account_password, :token)");
$statement->execute(array(
":entry_time" => time(),
":account_email" => $_POST["email"],
":account_password" => $password,
":token" => $token
));
# send verification email
include "include/sanitize.php";
$email = sanitize($_POST["email"]);
mail($_POST["email"],
"Account Verification",
"Please click the following link to activate your account: http://www.pillar.fyi/redflagreviews/signinup.php/?email=".$email."&token=".$token,
"From: aj#pillar.fyi",
"-f aj#pillar.fyi");
}
}
$connect = null;
}
else # sign in
{
$statement = $connect->prepare("SELECT account_password FROM users_verified WHERE account_email = :account_email");
$statement->bindParam(":account_email", $_POST["email"]);
$statement->execute();
$result = $statement->fetch(PDO::FETCH_ASSOC);
if ($result["account_password"]
&& password_verify($_POST["password"], $result["account_password"])) # successfully logged in, redirect to main page
{
$connect = null;
$_SESSION["session"] = $_POST["email"];
echo "<script type='text/javascript'> location.href = 'http://www.pillar.fyi/redflagreviews/index.php' </script>";
}
else if ($result["account_password"]) # failed login
{
echo "That is the wrong password.";
$idPersist = $_POST["email"]; # maybe sanitize?
}
else {
echo "That account does not exist.";
}
}
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<!--link href="css/index.css" rel="stylesheet"-->
</head>
<body>
<form accept-charset="UTF-8" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" enctype="application/x-www-form-urlencoded" method="POST">
<input type="range" name="action"
min="0" max="1" step="1" value="0" id="action"
> <!-- use PHP variable to set as register or sign in -->
<input type="text" name="email" placeholder="email" value="<?php echo $idPersist; ?>" <?php if (!$idPersist) echo "autofocus"; ?> required>
<input type="password" name="password" placeholder="password" <?php if ($idPersist) echo "autofocus"; ?> required autocomplete>
<input type="submit" value="➥">
</form>
<!--script type="text/javascript" src="js/index.js"></script-->
</body>
</html>
Related
Errors
I have written a PHP program which take user new and old password my code is running well but now I have to few lines of code in my PHP program.
This is my code of PHP which I written and I want to add few lines of code in it but when I write new code in it works but it shows new errors, that code which I have to written is warning to user that user "new password should be different with old password". This code warns user when user enter on submit button of new password same as old password webpage.
This is my PHP program:
<?php
session_start();
// if ($_SESSION['user_name'] != "")
// {
// header("location:account.php");
// }
include('connection.php');
// header("Refresh: 20; URL=welcome.php");
// header("Refresh: 20; URL=http://www.stackoverflow.com/");
if(isset($_POST['submit']))
{
$old_password = $_POST['old_password'];
$new_password = $_POST['new_password'];
$query = $con->prepare("select password from tbl_users WHERE id = :user_id");
$query->bindParam(':user_id', $_SESSION['id']);
$query->setFetchMode(PDO::FETCH_ASSOC);
$query->execute();
$fetch = $query->fetch();
$old_pass = $fetch['password'];
if($old_password == $old_pass){
$stmt = $con->prepare("UPDATE tbl_users SET password = (:pass) WHERE id = :user_id");
$stmt->bindParam(':pass', $new_password, PDO::PARAM_STR);
$stmt->bindParam(':user_id', $_SESSION['id']);
// $stmt->execute();
$stmt->execute();
header("location:account.php");
}
else
{
echo "<script>alert('Wrong password! Enter your valid old password')</script>";
}
}
?>
HTML Code:
<!DOCTYPE html>
<html>
<head>
<title>project</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="registration.css">
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
</head>
<body>
<header><h1>Change Password</h1></header>
<form method="post" action="renew.php">
<br />
<input type="password" id="pwd2" placeholder="Enter your old password" name="old_password" required />
<br />
<input type="password" id="pwd1" placeholder="Enter your new password" name="new_password" required />
<center>
<!-- <div class="form-group"> -->
<div id="setPasswordMessage" style="display: none;"></div>
<!-- </div> -->
</center>
<br />
<div class="buttons">
<input type="submit" disabled="submit" class="btn" name="submit" value="Save">
</div>
<br />
</form>
<footer><h3>Copyright © vu.edu.pk (S1701F607E)</h3></footer>
<script type="text/javascript">
$(document).ready(function() {
var pwd1 = $('#pwd1'); //id of first password field
var pwd2 = $('#pwd2'); //id of second password field
var pwdIdSet = $('#setPasswordMessage'); //id of indicator element
setCheckPasswordStrength(pwd1,pwd2,pwdIdSet); //call password check function
});
function setCheckPasswordStrength(pwd1, pwd2, pwdIdSet)
{
/*=========== Start: Set Password Cretria Regular Expression ===================*/
//Password must contain 5 or more characters
var lowPassword = /(?=.{5,}).*/;
//Password must contain at least one digit and lower case letters .
var mediumPassword = /^(?=\S*?[a-z])(?=\S*?[0-9])\S{5,}$/;
//Password must contain at least one digit, one upper case letter and one lower case letter.
var averagePassword = /^(?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[0-9])\S{5,}$/;
//Password must contain at least one digit, one upper case letter and one lower case letter.
var strongPassword = /^(?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[0-9])(?=\S*?[^\w\*])\S{5,}$/;
/*=========== End: Set Password Cretria Regular Expression ===================*/
// test() method is used to test match in a string whether the value is matched in a string or not.
$(pwd1).on('keyup', function(e) {
var len = $('#pwd1').val().length;
document.getElementById("setPasswordMessage").style.display="block";
if(strongPassword.test(pwd1.val()))
{
pwdIdSet.removeClass().addClass('strongPassword').html("Strong! Please use this password!").css("display","block");
$(':input[type="submit"]').prop('disabled', false);
}
else if(averagePassword.test(pwd1.val()))
{
pwdIdSet.removeClass().addClass('averagePassword').html("Average! Tips: Enter special characters to make even stronger").css("display","block");
$(':input[type="submit"]').prop('disabled', true);
}
else if(mediumPassword.test(pwd1.val()))
{
pwdIdSet.removeClass().addClass('mediumPassword').html("Good! Tips: Enter uppercase letter to make strong").css("display","block");
$(':input[type="submit"]').prop('disabled', true);
}
else if(lowPassword.test(pwd1.val()))
{
pwdIdSet.removeClass().addClass('stilllowPassword').html("Still Weak! Tips: Enter digits to make good password").css("display","block");
$(':input[type="submit"]').prop('disabled', true);
}
else if(len < 1)
{
pwdIdSet.removeClass('lowPassword');
$('#setPasswordMessage').css("display","none");
$(':input[type="submit"]').prop('disabled', true);
}
else
{
pwdIdSet.removeClass().addClass('lowPassword').html("Very Weak! Please use 5 or more chars password)").css("display","block");
$(':input[type="submit"]').prop('disabled', true);
}
});
// $(pwd2).on('keyup', function(e) {
// if(pwd1.val() !== pwd2.val())
// {
// pwdIdSet.removeClass().addClass('lowPassword').html("Passwords do not match!");
// }else{
// pwdIdSet.removeClass().addClass('goodpass').html("Passwords match!");
// }
// });
}
</script>
</body>
</html>
I have to add this code in PHP code but in which place and how.
if($old_password == $new_password)
{
echo "<script>alert('New password should be different with old password')</script>";
}
Put the check right before you do the query.
<?php
session_start();
// if ($_SESSION['user_name'] != "")
// {
// header("location:account.php");
// }
include('connection.php');
// header("Refresh: 20; URL=welcome.php");
// header("Refresh: 20; URL=http://www.stackoverflow.com/");
if(isset($_POST['submit']))
{
$old_password = $_POST['old_password'];
$new_password = $_POST['new_password'];
if ($old_password == $new_password) {
echo "<script>alert('New password should be different with old password')</script>";
} else {
$query = $con->prepare("select password from tbl_users WHERE id = :user_id");
$query->bindParam(':user_id', $_SESSION['id']);
$query->setFetchMode(PDO::FETCH_ASSOC);
$query->execute();
$fetch = $query->fetch();
$old_pass = $fetch['password'];
if($old_password == $old_pass){
$stmt = $con->prepare("UPDATE tbl_users SET password = (:pass) WHERE id = :user_id");
$stmt->bindParam(':pass', $new_password, PDO::PARAM_STR);
$stmt->bindParam(':user_id', $_SESSION['id']);
// $stmt->execute();
$stmt->execute();
header("location:account.php");
}
else
{
echo "<script>alert('Wrong password! Enter your valid old password')</script>";
}
}
}
?>
PHP throws error if header is sent after any output. Thus, if you have any output before header("location:account.php");, an error will occur. Try setting new location via JS instead:
// header("location:account.php");
echo "<script>document.location.href = 'account.php';</script>";
the full code will look something like this:
if($old_password == $old_pass){
if($old_password == $new_password)
{
echo "<script>alert('New password should be different with old password')</script>";
} else {
$stmt = $con->prepare("UPDATE tbl_users SET password = (:pass) WHERE id = :user_id");
$stmt->bindParam(':pass', $new_password, PDO::PARAM_STR);
$stmt->bindParam(':user_id', $_SESSION['id']);
// $stmt->execute();
$stmt->execute();
// header("location:account.php");
echo "<script>document.location.href = 'account.php';</script>";
}
}
else....
You should put this check after you set the variables $old_password and $new_password and before you execute any database queries (you don't want to execute these if old and new password are the same):
if(isset($_POST['submit']))
{
$old_password = $_POST['old_password'];
$new_password = $_POST['new_password'];
if($old_password == $new_password)
{
echo "<script>alert('New password should be different with old password')</script>";
}
else
{
$query = $con->prepare("select password from tbl_users WHERE id = :user_id");
$query->bindParam(':user_id', $_SESSION['id']);
$query->setFetchMode(PDO::FETCH_ASSOC);
$query->execute();
$fetch = $query->fetch();
$old_pass = $fetch['password'];
if($old_password == $old_pass){
$stmt = $con->prepare("UPDATE tbl_users SET password = (:pass) WHERE id = :user_id");
$stmt->bindParam(':pass', $new_password, PDO::PARAM_STR);
$stmt->bindParam(':user_id', $_SESSION['id']);
// $stmt->execute();
$stmt->execute();
header("location:account.php");
}
else
{
echo "<script>alert('Wrong password! Enter your valid old password')</script>";
}
}
}
And while it has nothing to do with coding, I just wanted to note that your error message is not correct English. Something is "different from" something else, not "different with". Use this:
Your new password must be different from your old password
I have been working on a website on a localhost and have just tried to upload it to a free webserver so I can get some testers, for some reason my code is being reported as malware and is being blocked by my antivirus, this means I can't see anything when visiting it apart from the ERR_CONNECTION_RESET. Have you guys got any ideas as to why this code is being detected as malware?
LOGIN.php
<?php
include('classes/db.php');
if (db::maintenance()) {
die('This site is currently going under maintenance, please check back again shortly.');
}
if (isset($_POST['submit'])) {
$username = $_POST['username'];
$password = $_POST['password'];
if (db::query('SELECT username FROM users WHERE username=:username', array(':username'=>$username))) {
if (password_verify($password, db::query('SELECT password FROM users WHERE username=:username', array(':username'=>$username))[0]['password'])) {
echo "Logged in!";
$cstrong = True;
$token = bin2hex(openssl_random_pseudo_bytes(64, $cstrong));
$user_id = db::query('SELECT id FROM users WHERE username=:username', array(':username'=>$username))[0]['id'];
db::query('INSERT INTO login_tokens VALUES (NULL, :token, :user_id)', array(':token'=>sha1($token), ':user_id'=>$user_id));
setcookie("SNID", $token, time() + 60 * 60 * 24 * 7, '/', NULL, NULL, TRUE);
setcookie('SNID_', '1', time() + 60 + 60 * 24 * 3, '/', NULL, NULL, TRUE);
header('Location: index.php');
} else {
echo "Incorrect password";
}
} else {
echo "User not registered!";
}
}
?>
<h1>Login to your account</h1>
<form action="login.php" method="post">
<input type="text" name="username" value="" placeholder="Username"><p />
<input type="password" name="password" value="" placeholder="Password"><p />
<input type="submit" name="submit" placeholder="Login"><p />
</form>
DB.php
(I have changed the connection to false data, and changed it to the correct data when uploading it to the host.)
<?php
class db {
private static function connect () {
$conn = new PDO('mysql:host=localhost;dbname=users;,charset=utf8', 'root', '');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
}
public static function query ($sql, $params = array()) {
$statement = self::connect()->prepare($sql);
$statement->execute($params);
if (explode(' ', $sql)[0] == 'SELECT') {
$result = $statement->fetchAll();
return $result;
}
}
public static function notify ($userid) {
$notifications = db::query('SELECT forum_members.forum_id, notifications.user_id, notifications.post_id, notifications.forum_id, notifications.post_body, notifications.creation, notifications.type FROM forum_members, notifications WHERE (notifications.forum_id=forum_members.forum_id OR notifications.forum_id=0) AND notifications.user_id=forum_members.user_id ORDER BY notifications.post_id DESC');
return $notifications;
}
public static function maintenance () {
return false;
}
}
?>
Which type of address do you use to enter the website? PHP source doesn't display to browsers, so PHP isn't the problem.
If you enter in with a hostname (Ex. .....2cc.brad....net) Then it'll automatically get detected as a "malware" for beginner safety, if ur accessing it from localhost/127.0.0.1 it should be fine, but if ur accessing it from a host that's marked as malware, than yep.
I have a login script and a functions.php script to check if the session username and cookie are set. When the user logs in, if they select the remember me, the cookie is supposed to set. But the problem is that, the script works, but the cookie doesn't set so the user is not being logged in. I've searched through so many topics on here and tried as many solutions as possible, but I still either get the same result or end up giving me more errors.
if (isset($_POST['rem']) && $_POST['rem'] == 'on') > {
setcookie('MCLatestUser', $token, 31622400, > '/');
session_regenerate_id(true);
}
This is the part of the code that should set the cookie if remember is checked.
Log.php (Since I use an ajax login script, the url is set to this):
<?php
include_once 'db.php';
include_once 'functions.php';
error_reporting(-1);
if(isset($_POST['email'])) {
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_STRING);
$password = $mysqli->real_escape_string($_POST['password']);
try {
$check = mysqli_query($mysqli, "SELECT * FROM users WHERE email='$email'");
$res = mysqli_num_rows($check);
if($res > 0) {
while($run = mysqli_fetch_array($check, MYSQLI_ASSOC)) {
$blocked = $run['blocked'];
$deactivated = $run['deactivated'];
$paused = $run['paused'];
$verified = $run['verified'];
$rank = $run['rank'];
$token = $run['token'];
$pass = $run['password'];
$pbackup = $run['pbackup'];
if($verified == 'true') {
if($blocked == 'true') {
echo 'Looks like your account was blocked. If you think this is an error, please contact an admin via support#mclatest.com';
} else if($deactivated == 'true') {
echo 'Looks like your account has been deactivated. If you think this is an error, please contact an admin via support#mclatest.com';
} else if($paused == 'true') {
echo 'Looks like your account is frozen. If you think this is an error, please contact an admin via support#mclatest.com';
} else {
if(password_verify($password, $pass)) {
$timestamp = time();
// Authenticated, set session variables
$_SESSION['username'] = $run['username'];
if (isset($_POST['rem']) && $_POST['rem'] == 'on') {
setcookie('MCLatestUser', $token, 31622400, '/');
session_regenerate_id(true);
}
$sql = mysqli_query($mysqli, "UPDATE users SET Ip = '$ipaddress', login_ip = '$ipaddress', latest_login_date = '$now', login_date = '$date', login_time = '$time', login_day = '$day', login_month = '$month', login_year = '$year', status = '$timestamp' WHERE email = '$email'");
if($sql) {
echo "Success!";
} else {
echo "Error login in";
}
// do stuffs
} else if(password_verify($password, $pbackup)) {
$timestamp = time();
// Authenticated, set session variables
$_SESSION['username'] = $run['username'];
if (isset($_POST['rem']) && $_POST['rem'] == 'on') {
setcookie('MCLatestUser', $token, 31622400, '/');
session_regenerate_id(true);
}
$sql = mysqli_query($mysqli, "UPDATE users SET Ip = '$ipaddress', login_ip = '$ipaddress', latest_login_date = '$now', login_date = '$date', login_time = '$time', login_day = '$day', login_month = '$month', login_year = '$year', status = '$timestamp' WHERE email = '$email'");
if($sql) {
echo "Success!";
} else {
echo "Error login in";
}
// do stuffs
} else {
echo "<h4 style='font-weight:bold;font-family:arial;margin:8px'>Your password is incorrect, please try again. If you still get this error after using your backup password, please <a href='https://mclatest.com/community/reset.php?r=password'>reset</a> your password</h4>";
}
}
} else {
echo "<h4 style='font-weight:bold;font-family:arial;margin:8px'>You need to verify your account. Please click this link to <a href='https://mclatest.com/community/confirm.php?email=".$email."&token=".$token."'>verify your account</a></h4>";
}
}
} else {
echo 'No records of that user have been found!';
}
} catch(PDOException $e){
echo $e->getMessage();
}
} else {
echo "Invalid email";
}
Login.php (the html and ajax form):
<form id="login_form" style="text-align:center" method="post">
<script>
$(document).ready(function() {
$("#login").click(function(e) {
e.preventDefault();
var email = $("#email").val();
if (email = "") {
$("#error_msg").html("<h4>Email cannot be empty</h4>");
} else {
var data = $("#login_form").serialize();
$.ajax({
type: "POST",
url: "../inc/log.php",
data: data,
beforeSend: function() {
$("#error_msg").fadeOut();
$("#login").val('sending ...');
},
success: function(data) {
if (data == "Success!") {
// alert("Works"); //for testing purposes
window.location.href = "index.php";
} else {
$("#error_msg").fadeIn(1000, function() {
$("#error_msg").html('<div style="border:1px solid: red; background:rgba(255,0,0,0.9;)">'+data+'!</div>');
$("#login").val('Login');
});
}
},
error: function(data) {
alert("Process Failed!");
}
});
return false;
}
});
});
</script>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label ">
<label for="input_email" class="mdl-textfield__label">Email</label>
<input type="email" name="email" class="mdl-textfield__input" maxlength="255" id="input_email" />
</div>
<br>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<label for="input_password" class="mdl-textfield__label">Password</label>
<input type="password" name="password" class="mdl-textfield__input" maxlength="255" id="input_password" />
</div>
<br>
<label style="width:auto !important" for="remember_me" class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" >
<input name="rem" type="checkbox" id="remember_me" class="mdl-checkbox__input" checked />
<span class="mdl-checkbox__label">Stay logged in?</span>
</label>
<br>
<nav style="width:auto !important;display:-webkit-box;-webkit-box-pack:center" class="mdl-navigation">
<a class="mdl-navigation__link" href="forgot.php?ftype=password">Forgot Password?</a> |
<a class="mdl-navigation__link" href="register.php">Register?</a>
</nav>
<br>
<input type="submit" id="login" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" name="login" value="Login"/>
</form>
functions.php (this is the portion of the script to check the session and cookie variables):
function loggedIn() {
if (isset($_SESSION['username']) && !empty($_SESSION['username']) && isset($_COOKIE['MCLatestUser'])) {
return true;
} else {
return false;
}
}
Script works but cookies aren't being sent. I'm at my wits end here, been working on this for over 4-5 hours now, had over 35 chrome tabs open just to figure this out. I am probably overlooking a minor detail. Login Page Link
It works if i remove the && $_COOKIE['MCLatestUser'] from the function script
setcookie('MCLatestUser', $token, 31622400, '/');
This method has some problems in the third parameter.It should be based on the current time.
PHP: setcookie - Manual
I figured it out. It turns out it was the browser's fault. I tried it on Microsoft Edge and Mozilla Firefox and it worked. So I looked about for that issue and all I had to do was clear my cookies and site data on chrome. Thank you to those who helped and those who wanted to but couldn't/didn't.
I have been struggling with this one for hours and hours and just cannot figure out what I'm missing.
I'm trying to build a cookie-less login form that also has no information in session variables that would harm the app if an attacker would be able to modify them.
All of my pages have the below code included.
I have 2 issues:
Every time I click on another page it acts like $_SESSION['token'] was empty and goes to the login page like if it was the first visit.
It returns $tokenid and $tokentype empty however I'm calling them both every time a page is loading (aiming to avoid having to put them into a session variable).
This is my current code:
<?php
define('TIMEOUTMIN', 15);
define('LOCKOUTMIN', 10);
define('LOCKOUTNUM', 3);
include("includes/pp/pbkdf2.php"); // this is basically calling the validate_password function
include ("includes/vars/vars_dbconn.php"); // this contains the db data and $pdo
$userid = $_POST['userid'];
$userpw = $_POST['password'];
$deltoq = "UPDATE LoginUser SET token = ?, online = ? WHERE online < ?";
$prepdeltoq = $pdo->prepare($deltoq);
$prepdeltoq->execute(array(NULL,NULL,time()));
$loginq = "SELECT * FROM LoginUser WHERE ID = ?";
$preplq = $pdo->prepare($loginq);
$preplq->execute(array($userid));
$getuser = $preplq->fetch(PDO::FETCH_ASSOC);
$dbid = $getuser['ID'];
$dbpass = $getuser['hash'];
$dbbp = $getuser['bp'];
$dbltime = $getuser['ltimeout'];
$logintoq = "SELECT * FROM LoginUser WHERE token = ?";
$prepltq = $pdo->prepare($logintoq);
$prepltq->execute(array($_SESSION['token']));
$getoken = $prepltq->fetch(PDO::FETCH_ASSOC);
$tokenid = $getoken['ID'];
$tokentype = $getoken['type'];
$totoken = $getoken['token'];
$prolonglock = $pdo->prepare("UPDATE LoginUser SET ltimeout = ? WHERE ID = ?");
$addbp = $pdo->prepare("UPDATE LoginUser SET bp = ? WHERE ID = ?");
$loginwhen = $pdo->prepare("UPDATE LoginUser SET lastlogin = ? WHERE ID = ?");
$loginlogq = $pdo->prepare("INSERT INTO LoginUserLog (ID, action)
VALUES(:ID, :action)");
$logintokenid = $pdo->prepare("UPDATE LoginUser SET token = ? WHERE ID = ?");
$loginonid = $pdo->prepare("UPDATE LoginUser SET online = ? WHERE ID = ?");
$loginontok = $pdo->prepare("UPDATE LoginUser SET online = ? WHERE token = ?");
if(!function_exists('LoginUser')) {
function LoginUser($pwmessage) {
if (session_name() <> 'MyWebApp') session_name('WesoftskyLogin');
if (!session_id()) session_start();
$_SESSION['token'] = '';
include ("includes/header.php"); ?>
<meta name="description" content="Login - MyWebApp"/>
<title>Login - MyWebApp</title>
<script type="text/javascript">
event.keyCode == '';
function enterTab() {
if (event.keyCode == 13) {
var passInput = document.getElementById("password");
passInput.focus();
}
}
</script>
</head>
<body onkeyup="enterTab()">
<div id="homewrap">
<div id="hometitle">MyWebApp</div>
</div>
<div id="id_formwrap">
<form action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']); ?>" method="post">
<?php if (empty($pwmessage)) echo '<div>Please enter your login details</div>'; else echo '<div style="color:red">'.$pwmessage.'</div>'; ?><br />
Login ID<br />
<input type="text" name="userid" id="id" onKeyPress="return noenter(event)" /><br /><br />
<script>document.getElementById("id").focus()</script>
Password<br />
<input type="password" name="password" id="password" /><br /><br />
<input type="submit" name="login" id="Submit" value="Login" />
</form>
</div>
</body>
</html>
<?php exit();
}
}
if(!function_exists('ProlongTime')) {
function ProlongTime() {
global $userid;
global $logintokenid;
global $loginonid;
global $loginontok;
$timeoutodb = (time () + TIMEOUTMIN*60);
if (!empty($userid)) {
$_SESSION['token'] = bin2hex(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM));
$logintokenid->execute(array($_SESSION['token'], $userid));
$loginonid->execute(array($timeoutodb, $userid));
} else {
$loginontok->execute(array($timeoutodb, $_SESSION['token']));
}
}
}
if ($dbltime > time()) {
$lockcheck = time() + LOCKOUTMIN*60;
$prolonglock->execute(array($lockcheck,$userid));
LoginUser('Your account is currently locked');
}
if(isset($_POST['logout'])) {
$action = "Logged OUT";
$loginlogq->execute(array(':ID' => $tokenid, ':action' => $action));
LoginUser('Logged out');
}
if (isset($_POST['login'])) {
if ($dbid AND validate_password($userpw, $dbpass)) { // Good login info
//session_regenerate_id(true);
$action = "Logged IN";
$loginlogq->execute(array(':ID' => $userid, ':action' => $action));
$loginwhen->execute(array(time(), $userid));
$addbp->execute(array(NULL, $userid));
ProlongTime();
} else { // Bad login info
if ($dbbp >= LOCKOUTNUM-1) {
$lockbp = time() + LOCKOUTMIN*60;
$prolonglock->execute(array($lockbp,$userid));
$action = "Locked (wrong password)";
$loginlogq->execute(array(':ID' => $userid, ':action' => $action));
LoginUser('Your account has been locked');
}
$addbp->execute(array($dbbp+1, $userid));
$action = "Failed login";
$loginlogq->execute(array(':ID' => $userid, ':action' => $action));
LoginUser('Username or password is incorrect');
}
} elseif (empty($_SESSION['token'])) { // Loading the page first time (new session)
LoginUser('');
} elseif ($_SESSION['token'] <> $totoken) { // Session timeout
$action = "Logged OUT (expired)";
$loginlogq->execute(array(':ID' => $tokenid, ':action' => $action));
echo 'tokenid: '.$tokenid;
} else ProlongTime(); // While using the app and still within time
$pdo = null;
?>
You need to put
session_start()
in the starting of the page.
I'm trying to add a login form onto my free mathhelp site, but whenever i include the form in my index page, it is hiding the rest of the site. Here is the source code all credit to Codex-m:
<?php
session_start();
//require user configuration and database connection parameters
require('config.php');
if (($_SESSION['logged_in'])==TRUE) {
//valid user has logged-in to the website
//Check for unauthorized use of user sessions
$iprecreate= $_SERVER['REMOTE_ADDR'];
$useragentrecreate=$_SERVER["HTTP_USER_AGENT"];
$signaturerecreate=$_SESSION['signature'];
//Extract original salt from authorized signature
$saltrecreate = substr($signaturerecreate, 0, $length_salt);
//Extract original hash from authorized signature
$originalhash = substr($signaturerecreate, $length_salt, 40);
//Re-create the hash based on the user IP and user agent
//then check if it is authorized or not
$hashrecreate= sha1($saltrecreate.$iprecreate.$useragentrecreate);
if (!($hashrecreate==$originalhash)) {
//Signature submitted by the user does not matched with the
//authorized signature
//This is unauthorized access
//Block it
header(sprintf("Location: %s", $forbidden_url));
exit;
}
//Session Lifetime control for inactivity
//Credits: http://stackoverflow.com/questions/520237/how-do-i-expire-a-php-session-after-30-minutes
if ((isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > $sessiontimeout))) {
session_destroy();
session_unset();
//redirect the user back to login page for re-authentication
$redirectback=$domain.'securelogin/';
header(sprintf("Location: %s", $redirectback));
}
$_SESSION['LAST_ACTIVITY'] = time();
}
//Pre-define validation
$validationresults=TRUE;
$registered=TRUE;
$recaptchavalidation=TRUE;
//Trapped brute force attackers and give them more hard work by providing a captcha-protected page
$iptocheck= $_SERVER['REMOTE_ADDR'];
$iptocheck= mysql_real_escape_string($iptocheck);
if ($fetch = mysql_fetch_array( mysql_query("SELECT `loggedip` FROM `ipcheck` WHERE `loggedip`='$iptocheck'"))) {
//Already has some IP address records in the database
//Get the total failed login attempts associated with this IP address
$resultx = mysql_query("SELECT `failedattempts` FROM `ipcheck` WHERE `loggedip`='$iptocheck'");
$rowx = mysql_fetch_array($resultx);
$loginattempts_total = $rowx['failedattempts'];
If ($loginattempts_total>$maxfailedattempt) {
//too many failed attempts allowed, redirect and give 403 forbidden.
header(sprintf("Location: %s", $forbidden_url));
exit;
}
}
//Check if a user has logged-in
if (!isset($_SESSION['logged_in'])) {
$_SESSION['logged_in'] = FALSE;
}
//Check if the form is submitted
if ((isset($_POST["pass"])) && (isset($_POST["user"])) && ($_SESSION['LAST_ACTIVITY']==FALSE)) {
//Username and password has been submitted by the user
//Receive and sanitize the submitted information
function sanitize($data){
$data=trim($data);
$data=htmlspecialchars($data);
$data=mysql_real_escape_string($data);
return $data;
}
$user=sanitize($_POST["user"]);
$pass= sanitize($_POST["pass"]);
//validate username
if (!($fetch = mysql_fetch_array( mysql_query("SELECT `username` FROM `authentication` WHERE `username`='$user'")))) {
//no records of username in database
//user is not yet registered
$registered=FALSE;
}
if ($registered==TRUE) {
//Grab login attempts from MySQL database for a corresponding username
$result1 = mysql_query("SELECT `loginattempt` FROM `authentication` WHERE `username`='$user'");
$row = mysql_fetch_array($result1);
$loginattempts_username = $row['loginattempt'];
}
if(($loginattempts_username>2) || ($registered==FALSE) || ($loginattempts_total>2)) {
//Require those user with login attempts failed records to
//submit captcha and validate recaptcha
require_once('recaptchalib.php');
$resp = recaptcha_check_answer ($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]);
if (!$resp->is_valid) {
//captcha validation fails
$recaptchavalidation=FALSE;
} else {
$recaptchavalidation=TRUE;
}
}
//Get correct hashed password based on given username stored in MySQL database
if ($registered==TRUE) {
//username is registered in database, now get the hashed password
$result = mysql_query("SELECT `password` FROM `authentication` WHERE `username`='$user'");
$row = mysql_fetch_array($result);
$correctpassword = $row['password'];
$salt = substr($correctpassword, 0, 64);
$correcthash = substr($correctpassword, 64, 64);
$userhash = hash("sha256", $salt . $pass);
}
if ((!($userhash == $correcthash)) || ($registered==FALSE) || ($recaptchavalidation==FALSE)) {
//user login validation fails
$validationresults=FALSE;
//log login failed attempts to database
if ($registered==TRUE) {
$loginattempts_username= $loginattempts_username + 1;
$loginattempts_username=intval($loginattempts_username);
//update login attempt records
mysql_query("UPDATE `authentication` SET `loginattempt` = '$loginattempts_username' WHERE `username` = '$user'");
//Possible brute force attacker is targeting registered usernames
//check if has some IP address records
if (!($fetch = mysql_fetch_array( mysql_query("SELECT `loggedip` FROM `ipcheck` WHERE `loggedip`='$iptocheck'")))) {
//no records
//insert failed attempts
$loginattempts_total=1;
$loginattempts_total=intval($loginattempts_total);
mysql_query("INSERT INTO `ipcheck` (`loggedip`, `failedattempts`) VALUES ('$iptocheck', '$loginattempts_total')");
} else {
//has some records, increment attempts
$loginattempts_total= $loginattempts_total + 1;
mysql_query("UPDATE `ipcheck` SET `failedattempts` = '$loginattempts_total' WHERE `loggedip` = '$iptocheck'");
}
}
//Possible brute force attacker is targeting randomly
if ($registered==FALSE) {
if (!($fetch = mysql_fetch_array( mysql_query("SELECT `loggedip` FROM `ipcheck` WHERE `loggedip`='$iptocheck'")))) {
//no records
//insert failed attempts
$loginattempts_total=1;
$loginattempts_total=intval($loginattempts_total);
mysql_query("INSERT INTO `ipcheck` (`loggedip`, `failedattempts`) VALUES ('$iptocheck', '$loginattempts_total')");
} else {
//has some records, increment attempts
$loginattempts_total= $loginattempts_total + 1;
mysql_query("UPDATE `ipcheck` SET `failedattempts` = '$loginattempts_total' WHERE `loggedip` = '$iptocheck'");
}
}
} else {
//user successfully authenticates with the provided username and password
//Reset login attempts for a specific username to 0 as well as the ip address
$loginattempts_username=0;
$loginattempts_total=0;
$loginattempts_username=intval($loginattempts_username);
$loginattempts_total=intval($loginattempts_total);
mysql_query("UPDATE `authentication` SET `loginattempt` = '$loginattempts_username' WHERE `username` = '$user'");
mysql_query("UPDATE `ipcheck` SET `failedattempts` = '$loginattempts_total' WHERE `loggedip` = '$iptocheck'");
//Generate unique signature of the user based on IP address
//and the browser then append it to session
//This will be used to authenticate the user session
//To make sure it belongs to an authorized user and not to anyone else.
//generate random salt
function genRandomString() {
//credits: http://bit.ly/a9rDYd
$length = 50;
$characters = "0123456789abcdef";
for ($p = 0; $p < $length ; $p++) {
$string .= $characters[mt_rand(0, strlen($characters))];
}
return $string;
}
$random=genRandomString();
$salt_ip= substr($random, 0, $length_salt);
//hash the ip address, user-agent and the salt
$useragent=$_SERVER["HTTP_USER_AGENT"];
$hash_user= sha1($salt_ip.$iptocheck.$useragent);
//concatenate the salt and the hash to form a signature
$signature= $salt_ip.$hash_user;
//Regenerate session id prior to setting any session variable
//to mitigate session fixation attacks
session_regenerate_id();
//Finally store user unique signature in the session
//and set logged_in to TRUE as well as start activity time
$_SESSION['signature'] = $signature;
$_SESSION['logged_in'] = TRUE;
$_SESSION['LAST_ACTIVITY'] = time();
}
}
if (!$_SESSION['logged_in']):
?>
<!-- START OF LOGIN FORM -->
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="POST">
Username: <input type="text" class="<?php if ($validationresults==FALSE) echo "invalid"; ?>" id="user" name="user">
Password: <input name="pass" type="password" class="<?php if ($validationresults==FALSE) echo "invalid"; ?>" id="pass" >
<?php if (($loginattempts_username > 5) || ($registered==FALSE) || ($loginattempts_total> 5)) { ?>
Type the captcha below:
<?php
require_once('recaptchalib.php');
echo recaptcha_get_html($publickey);
?>
<?php } ?>
<?php if ($validationresults==FALSE) echo '<font color="red">Please enter valid username, password or captcha (if required).</font>'; ?>
<input type="submit" value="Login">
</form>
<!-- END OF LOGIN FORM -->
Register.
<?php
exit();
endif;
?>
what it looks like: http://i.imgur.com/bReQl.jpg, what it should look like: http://imgur.com/I0BsE.jpg (this is only after the user logs in., it should look like this before the user logs in with the login thing up the top) Basically it is hiding all the code underneath the login once it is embeded
thanks in advance for any help
The call to exit(); on the third to last line is causing the page to stop being printed out past that point. Remove that line to fix your problem.