I'm trying to write some code that will connect to a database called 'user' and find data from the 'password' field. I've got this PHP written so far:
$passw = $_POST['pass'];
$user = $_POST['user'];
$users_password_db = "SELECT password FROM 'user' WHERE username=$user";
$result = $mysqli->query($users_password_db);
if ($passw != $result){
$errors[] = "Incorrect username or password. Please try again, or contact the admin for support.";
}
else {
header('Location: /dashboard.php');
}
However, every time I log in with my correct username and password, it says that the password is wrong. I don't think this is a connection error, since I can add data into the database okay.
I'm just beginning with SQL, so sorry if this is an obvious question.
Make sure the username and password variables are correctly named both in your php code and the database. Capitalizations matter!
Related
I have a change password script which is supposed to reset a users password with the values they provide assuming they match however this script is breaking something as users are not able to login with the password they provide to the script.
I'm not sure what is wrong as I also have an add_user script which is what I use to create the user accounts. The code to generate the password (hash) is the same and the data is successfully being put into the DB so I really don't know what is causing the problem. I'm guessing it has something to do with the data being provided prior to PHP hashing it thus in the DB it looks like it all went well as it's already hashed but I'm guessing if I was storing in plaintext it wouldn't be exactly the same as what the user entered otherwise the script would be working...
I've been working on the site all day so I'm really struggling to spot the error here.
I think my script used to work as this is the first I'm noticing the issue however I don't remember making any changes to this script in particular so cannot figure out why it would suddenly stop working.
session_start();
define('MyConst', TRUE);
include "includes/server.php";
if (!(isset($_SESSION['name']) && $_SESSION['name'] != ''))
{
header("location:login.php");
}
$con = mysqli_connect($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME) or die(mysqli_error($con));
$password1 = mysqli_real_escape_string($con, $_POST['newPassword']);
$password2 = mysqli_real_escape_string($con, $_POST['confirmPassword']);
$username = mysqli_real_escape_string($con, $_SESSION['name']);
$passwordhashed = password_hash("$password1", PASSWORD_DEFAULT);
if ($password1 <> $password2)
{
echo "your passwords do not match";
$referrer = $_SERVER['HTTP_REFERER'];
header ("Refresh: 2;URL='$referrer'");
}
else if (mysqli_query($con, "UPDATE accounts SET password='$passwordhashed' WHERE username='$username'"))
{
echo "You have successfully changed your password.";
$referrer = $_SERVER['HTTP_REFERER'];
header ("Refresh: 2;URL='$referrer'");
}
else
{
mysqli_error($con);
}
mysqli_close($con);
Expected to check that passwords match and echo "You have successfully changed your password" if the change was successful and then redirect.
The form page was missing a method as I had forgotten to add one in so it was defaulting to _GET when the rest of the script was referencing _POST.
Fix was simply adding method as post.
I'm switching over to PDO and trying to make my passwords in the MySQL database a little bit more secure, but unfortunately I've run into a little bit of a problem.
When a user registers, their password is treated as follows:
$pass = sha1($_POST['pass']);
And when a user logs in, the password they provide is treated exactly the same ($pass = sha1($_POST['pass'];)
The idea is then that I compare the two, and if they match, the user is logged in. The difficulty is, even if I enter the same password - "password", for instance - the encrypted password put into the database on registration does not match the encryption of the password when the user attempts to log in.
Does anyone know what the issue might be?
Full code:
$user = $_POST['user'];
$pass = sha1($_POST['pass']);
echo $pass; // This was just to check the two passwords
$db = new PDO('this is all correct');
$query = $db->prepare('SELECT pass, id FROM users WHERE user=:user');
$query->bindParam(':user',$user);
$query->execute();
$result = $query->fetch();
$storedpass = $result['pass'];
$storedid = $result['id'];
if($storedpass === $pass) {
header("Location: index.php");
}
else {
echo "Something went wrong";
}
sha1 should not be used to hash passwords. See the notice in the docs. You should use the new password_hash function instead, and the matching will be handled for you by password_verify.
Switching to the new hashing functions would likely solve your password validation issue while at the same time making your app much, much more secure.
If your version of PHP is less than 5.5, the new functions aren't available. A version for PHP 5.3.7+ is available on Github https://github.com/ircmaxell/password_compat.
You'd actually be much better off doing something like this:
$user = $_POST['user'];
$pass = sha1($_POST['pass']);
echo $pass; // This was just to check the two passwords
$db = new PDO('this is all correct');
$query= $db->prepare("SELECT id FROM users where user=:user AND pass=:pass");
$query->execute(array(':user' => $user, ':pass' => $pass));
if ($query->rowcount() == 1){
// authenticated
}else{
// not authenticated
}
Don't know if this will solve your problem though.
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?