I have this user login process page. at this point the user has entered the info and all of this works BUT I cannot figure out how to pull the encrypted password out of the DB. I need to extract with the PASSWORD() function and do not know how. I know this is not the best way to do it but its what the assignment calls for. I have the problem section commented out I think thats what needs fixing.
//sets $query to read usnername and passowd from table
$query = "SELECT username,password,first_name,last_name FROM jubreyLogin WHERE username
= '$userName' AND password=password('$userPassword')";
$result = mysql_query($query,$db);
if(mysql_error())
{
echo $query;
echo mysql_error();
}
//reads data from table sets as an array
//checks to see if user is already registered
while($row=mysql_fetch_array($result))
{
if($userName == $row['username'] /*&& $userPassword == ($row['password'])*/)
{
$login = 'Y';
$welcome = "Welcome" . " " .$row['first_name']. " " .$row['last_name'];
$userName = $row['username'];
}
}
if ($login='Y')
{
setcookie('name',$welcome,time()+60*60*24*30);
setcookie('login',"Y",time()+60*60*24*30);
$_SESSION['username_login'] = $userName;
header('Location: welcome.php');
}
Here is the modified code that I should of posted first I need it to check user entered password in this case $userPassword with the encrypted password if its a match it will send the user into the next page of the site.
You don't need to see the password in clear text ( you can't even if you wanted to). As you are checking the record both on password and username you don't need the check in your if() statement. If there is any row found, that means the username/password combination was succesfful and the user can be deemed as logged in.
Edit:
The updated code doesn't really make any difference to the actual logic. The logic stays the same, you query the database with username AND encrypted password, if there is a match that means the user has the right to login, so you proceed with setting the cookies/session data and redirect. Although I do not really see the need for the login cookie and the welcome cookie cause you could simply put in both username, fname and lname in the session. If the session on the following pages contains username that means the user has logged in.
The code can go something like this:
//sets $query to read usnername and passowd from table
$query = "SELECT username,first_name,last_name FROM jubreyLogin WHERE username = '$userName' AND password=password('$userPassword')";
$result = mysql_query($query,$db);
if(mysql_error())
{
echo $query;
echo mysql_error();
}
// were any rows returned?
if(mysql_num_rows($result)){
list($userName, $firstName , $lastName) = mysql_fetch_row($result);
$welcome = "Welcome" . " " .$firstName. " " .$lastName;
setcookie('name',$welcome,time()+60*60*24*30);
setcookie('login',"Y",time()+60*60*24*30);
$_SESSION['username_login'] = $userName;
header('Location: welcome.php');
}
You should not be encrypting your passwords, you should be hashing them. Try using a library such as phpass to be on the safe side. What you will need to do is hash the passwords and store the hashed value in the database. When a user logs in, you will hash the password they provide and compare that with the hashed value in the database. If the hashes match, the password provided is correct. If not, you send an error to the user. You never need to be able to obtain the password in plain text in order to validate a user.
Also, make sure that you are either escaping your variables using mysql_real_escape_string() or prepared statements or your script will be vulnerable to SQL injection.
Related
So in my function I have the connection, the query which will result in 1 row and 1 column displayed. I then want to run the password_verify() This is where I am struggling. As the first parameter I have placed $pass which is user entered but then I need to get the result from the database to place in the 2nd parameter.
How would I do this?
function login($user, $pass){
$conn = connect();
$query = "SELECT password FROM account WHERE username = '$user' AND password = '$pass'";
$result = mysqli_query($conn, $query);
if (mysqli_num_rows($result)=== 1){
password_verify($pass, "$row[password]");
session_start();
If you do everything right your password field in a account table stores hashed password.
And argument $pass of a function is a plain password, I suppose.
So, your query
SELECT password FROM account WHERE username = '$user' AND password = '$pass'
will NEVER find any user, as you try to find user by plain password.
In addition - your $row variable is not defined.
What's the solution:
function login($user, $pass){
$conn = connect();
// do not add password to query
$query = "SELECT password FROM account WHERE username = '$user'";
$result = mysqli_query($conn, $query);
if (mysqli_num_rows($result) === 1){
// define $row
$row = mysqli_fetch_assoc($result);
// set proper quotes and compare password
// from db with password input by user
if (password_verify($pass, $row["password"])) {
// do something if password is correct
session_start();
And of course, instead of passing values directly to query, start using prepared statements.
When someone registers on your website, you have to use de built-in PHP function password_hash(). Also, I suggest naming it "password_hash" in your database and not "password" as to avoid confusion.
When someone tries to log in on your website, you have to use the built-in PHP password_verify() to compare the hashed password with the password.
// Login function
function login($user, $pass)
{
// Search the user by username
$conn = connect();
$query = "SELECT password_hashed FROM account WHERE username = '$user'";
$result = mysqli_query($conn, $query);
if (mysqli_fetch_row($result))
{
// We found the user, check if password is correct
if(password_verify($pass, $result["password_hashed"]))
{
return true;
}
else
{
return false;
}
}
else
{
// We didn't find the user
return false;
}
}
-Why should you hash the password when you store it into the database? Because when you store the password without hashing, the password in the database is exactly the same like what the user types in when registering. So when a hacker gets into the database, he sees the passwords of every user. If you hash the password, PHP makes the password into something completely else, that way when a hacker gets into the database he doesn't see the password but something completely else.
-The password_verify function is definitely the way to go when a user logs in. Just don't forget to add extra security when you enter data you receive from a user (through $_POST, $_GET, $_SESSION, ...) because when a user types in the follow name: my name" DROP TABLES account; they will delete all account informations.
I've got a simple contact form which posts two variables to PHP, to which I then insert to a database like so.
<?php
$username = $_POST["username"];
$password = $_POST["password"];
$db->query("INSERT INTO users (username,password) VALUES ('$username', '$password')");
?>
I've now created login.php, where I would like the user to be able to login using the information stored in the database. I'm not worried about security or anything, I'm just trying to ease myself into this. What would be the most simplest way to allow the user to login using their username and password?
error_reporting(0);
session_start();
include_once '../example.php';
/***************************** Step 2 ****************************/
if(isset($_REQUEST['admsubmit']))
{
$result=executeQuery("select * from adminlogin where admname='".htmlspecialchars($_REQUEST['name'],ENT_QUOTES)."' and admpassword='".md5(htmlspecialchars($_REQUEST['password'],ENT_QUOTES))."'");
// $result=mysqli_query("select * from adminlogin where admname='".htmlspecialchars($_REQUEST['name'])."' and admpassword='".md5(htmlspecialchars($_REQUEST['password']))."'");
if(mysqli_num_rows($result)>0)
{
$r=mysqli_fetch_array($result);
if(strcmp($r['admpassword'],md5(htmlspecialchars($_REQUEST['password'],ENT_QUOTES)))==0)
{
$_SESSION['admname']=htmlspecialchars_decode($r['admname'],ENT_QUOTES);
header('Location: admwelcome.php');
}else
{
echo "Check Your user name and Password.";
}
}
else
{
echo "Check Your user name and Password.";
}
closedb();
}
Go through the above code..its a simple example of check log in page post redirection by log in credentials form.
Assuming you don't want any security. I would do something like this:
$db->query("SELECT * from `users` where username = :username AND password = :password");
Replace the username and password with the user input.
WARNING: Don't use this on production environment. It's SQL injection vulnerable.
And you execute the query, Check the query row count, if it's equals to 1, it means there is a user with that username and password. if it equals to 0 it means, it's not found. You can then display errors or whatever.
Something like this in pseudo-code:
if(rowCount == 1) {
// log the user in
}
// Invalid credentials. Print some errors.
If you want security, Use PDO or mysqli functions. because mysql_* functions are deprecated and no longer maintained. and consider hashing your passwords, by using password_hash API.
I am creating a user form and form action where the user (already logged in using session variable) can change their md5 (i know MD5 is outdated and unsecured, this is for test purposes) encrypted account password stored in the sql database 'users' table.
I have a form which requests the inputs 'currentpassword', 'newpassword' and 'confirmnewpassword'. The form passes the entered data to passwordaction.php using $_POST.
The username is acquired from the $_SESSION 'autheticatedUser' and passwords acquired from the previous $_POST form variables. I then use an sql statement to get the password from the database for comparison to 'currentpassword' variable, DOES THIS COUNT AS INSECURE CLIENT SIDE VALIDATION? ?
I then have an SQL UPDATE statement to update the password row of the specified user in the database and the user is redirected and notified of success or failure using $_SESSION headers.
I have been reading and re-reading through my code trying to figure out where ive gone wrong as when trying to change a user account password I keep being returned to my login page (using $SESSION header) telling me it has updated properly however when i check the database the password has not been updated.
Im hoping someone elses view or perspective may be able to help me see what ive missed, can anyone suggest why my sql UPDATE statement is not working?
any constructive criticism welcome
below is my code for the 'action' php page
<?php
session_start();
$username = $_SESSION["authenticatedUser"];
$currentpassword = md5($_POST['currentpassword']);
$newpassword = md5($_POST['newpassword']);
$confirmnewpassword = md5($POST['confirmnewpassword']);
/* make a connection with database */
$con = mysql_connect("localhost", "root", "") or die(mysql_error());
/* select the database */
mysql_select_db("groupproject") or die(mysql_error());
$queryget = mysql_query("SELECT password FROM users WHERE username='$username'") or
die(mysql_error());
$row = mysql_fetch_assoc($queryget);
$currentpasswordDB = $row['password'];
//check passwords
if ($currentpassword==$currentpasswordDB)
{
if ($newpassword==$confirmnewpassword)
{
//success, change password in DB
$querychange = mysql_query("UPDATE users SET password='$newpassword' WHERE
username='$username'") or die(mysql_error());
}
else header("Location: passwordmismatch.php");
if ($querychange == true){
$_SESSION["passchange"] = "Your password has been changed, Please Log in";
header("Location:login.php");
}
else $_SESSION["nopasschange"] = "Your password could not be changed, Please try
again";
header("Location:userchangepassword.php");
}
else header("Location: passwordmismatch.php");
mysql_close($con);
?>
$user and $username are different variables.
Bit late :P
but in the row
$confirmnewpassword = md5($POST['confirmnewpassword']);
it should be
$confirmnewpassword = md5($_POST['confirmnewpassword']);
What I want to be able to do is: When a user enters their username and password in the form on the index.html page, if they match what is in the DB, then they get sent to the next page; userlogin.php.
If their username or password is incorrect then they are asked to re-enter their details on the index.html page, and displaying an error like, "Your username is Incorrect" or "Your password is Incorrect" above the form text box. I can paste this code if required.
Can I change this text font color as well, to red for example?
This is the code I currently have for the userlogin.php page
<?php
mysql_connect("Server", "root", "Gen") or die("Couldn't select database.");
mysql_select_db("generator") or die("Couldn't select database.");
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE Username = '$username' AND Password = '$password' ";
$result = mysql_query($sql) or die(mysql_error());
$numrows = mysql_num_rows($result);
if($numrows > 0)
{
echo 'Your in';
}
else
{
echo 'Your not in';
}
?>
There as sooo many things wrong with this code:
1- you have an SQL injection hole.
If I enter ' or 1=1 LIMIT 1 -- as a username, I will always get access, no matter what.
Change your code into.
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
See: How does the SQL injection from the "Bobby Tables" XKCD comic work?
2- you are storing the password in the clear
This is a huge no no. Combined with the SQL-injection hole, it will take a hacker 5 minutes to get a list of all usernames and passwords on your site.
Store the password as a salted hash.
I like to use the username as the salt.
You store the password hash using:
INSERT INTO users (username, passhash)
VALUES ('$username', SHA2(CONCAT('$password','$username'),512))
And you test the user credentials using:
SELECT * FROM users
WHERE username = '$username' AND
passhash = SHA2(CONCAT('$password','$username'),512)
See: Secure hash and salt for PHP passwords
And: What is "salt" when relating to MYSQL sha1?
BTW, use SHA2 with a 512 keylength, SHA1 is no longer secure, and MD5 is even more broken.
3- A login can only ever match against 1 user
This code:
if($numrows > 0)
Makes no sense, if you get 2 rows out of the database, that's a clear sign someone has hacked your system. The test should be:
if($numrows > 1) { //send email to sysadmin that my site has been hacked }
else if ($numrows = 0) { echo "wrong username or password" }
else { echo "welcome dr. Falken" }
4- Don't die if there's an error, call a routine to restart the connection or something
This code:
$result = mysql_query($sql) or die(mysql_error());
Is fine in testing, but in production you should do something like
$result = mysql_query($sql);
if ($result) {
//do the deed
} else {
//call error recovery routine
}
The error recovery routine should reconnect to the server, log a error in the logbook. Is the error cannot be fixed, it should send an email to the sysadmin and only then die the server.
First of all, your code is vulnerable to SQL injection. Use PDO and prepared statements to fix this. Second of all, you're appearantly storing usernames unencrypted. This is very unsafe. Use a hashing function to encrypt the passwords, and encrypt the submitted password before running the query to get a match. Coloring the output is simple:
echo '<span style="color:red">Your not in</span>';
And use sessions to actually log the user in. After successfully querying the user table for the username/password combination, store the returned user_id in the $_SESSION variable. On each page that needs to be secured, just check for the existence of $_SESSION['user_id']; if it isn't there, your user needs to login so redirect him to the login form.
That should about do the trick for ya ;)
Alright, I'm trying to make a login page. It seems that all of the pages worked pretty good- until I added salts. I don't really understand them, but doing something as basic as I am shouldn't be to hard to figure out. Here's "loginusr.php":
<html>
<body>
<?php
//form action = index.php
session_start();
include("mainmenu.php");
$usrname = mysql_real_escape_string($_POST['usrname']);
$pass = $_POST['password'];
$salt = $pass;
$password = sha1($salt.$pass);
$con = mysql_connect("localhost", "root", "g00dfor#boy");
if(!$con)
{
die("Unable to establish connection with host. We apologize for any inconvienience.");
}
mysql_select_db("users", $con) or die("Can't connect to database.");
$select = "SELECT * FROM data WHERE usrname='$usrname' and password='$password'";
$query = mysql_query($select);
$verify = mysql_num_rows($query);
if($verify==1)
{
$_SESSION["valid_user"] = $usrname;
header("location:index.php");
}
else
{
echo "Wrong username or password. Please check that CAPS LOCK is off.";
echo "<br/>";
echo "Back to login";
}
mysql_close($con);
?>
</body>
</html>
I used the command echo $password; to show me if the password in the database matched with the script. They did. What am I doing wrong?
It seems like you've misunderstood salts, since you're setting $salt to be the password.
A salt should be a completely random string that's stored in a user record along with the password hash. A new unique salt should be generated for every user. So you need to add a new column to your database, called "password_salt" or similar.
Rather than trying to use the password in the SELECT query and see if you get any records, you actually need to just SELECT using the username/user_id in order to get the password hash and salt so that you can then use those to determine if the user entered the correct password.
When you sign up new users you should add the fields with values like this,
<?php
// This is registeruser.php
$salt = substr(sha1(uniqid(rand(), true)), 0, 20);
$pass = $_POST['password'];
$pass_to_store = hash("sha256", $salt.$pass);
// Then issue a DB query to store the $salt and $pass_to_store in the user record.
// Do not store $pass, you don't need it.
// e.g. INSERT INTO users ('username', 'password_salt', 'password_hash') VALUES (:username, :salt, :pass_to_store);
?>
Then to check the password is the same when logging in, you do something like this,
<?php
// This is loginuser.php
$user = // result from SQL query to retrieve user record
// e.g. SELECT password_hash, password_salt FROM users WHERE username='from_user'
$salt_from_db = $user['password_salt'];
$pass_from_db = $user['password_hash'];
if ($pass_from_db == hash("sha256", $salt_from_db.$_POST['password'])
{
// Password matches!
}
?>
Don't forget to sanitize user inputs and anything you're putting into your database. You might want to look into using prepared statements instead of having to remember to use mysql_real_escape_string all the time.
It looks like you're salting with the same password? Normally a salt would be a random key that is specific to your site that you prepend to the password input, which it looks like you're doing fine. Just make sure you're using that same salt for checking that you use when the password is created.
Also, to use sessions properly you need to have session_start before anything is output to the page:
<?php
session_start();
?>
<html>
<body>
...
A salt is a random value to prevent an attacker from just looking up the source of a hash in table generated based on common passwords. (Using the username as salt is obviously not a good idea as it only adds very little entropy).
So you need to store the salt in the database and read it from the database in order to calculate the salted password hash for comparison with the stored value.
You misspelled username a couple of times, is it misspelled in the database, too?