How to make a change password PHP script work [closed] - php

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am a simpleton with less than a cursory knowledge of programming. I have a family web site where we share photos, videos, files and other resources. The site has a simple login feature that begins a session, and I want to be able to provide people with the ability to change their password once logged in.
The database is in MySQL and is extremely simple with only; ID, username, and, password columns (not encrypted or hashed at all).
When it comes to PHP and MySQL I tend to research other people's examples and make them my own, and with the login script I found this very easy to do. However, I have tried and tried and tried to find a PHP snippet that fits with my site and will allow users to change their passwords and have unfortunately failed at every attempt.
I am hoping that someone can assist me in developing what I have already to make it work for my site, any help will be hugely appreciated!
My form simply asks for the logged in user to enter a new password, and then confirm the same password:
<form name="frmChange" role="form" class="form-signin" method="POST" action="changepword_script.php">
<div class="form-group">
<label for="InputPassword2">New Password</label>
<input type="password" class="form-control" id="InputPassword2" placeholder="New Password" name="newPassword">
<label for="InputPassword3">Confirm New Password</label>
<input type="password" class="form-control" id="InputPassword3" placeholder="Confirm Password" name="confirmPassword"> </div>
<button class="btn btn-lrg btn-default btn-block" type="submit" value="send">Change it</button>
</div>
</form>
And my php script (also very simple) just needs to check that the passwords match and then update the database if they do (I have removed the IP address of the database and replaced with zeros):
<?php
session_start();
if (!(isset($_SESSION['username']) && $_SESSION['username'] != ''))
{
header("location:login.php");
}
$dbcon = mysql_connect ('000.000.000.00', 'my_db_username', 'my_db_password')
$password1 = $_POST['newPassword'];
$password2 = $_POST['confirmPassword'];
$password1 = mysql_real_escape_string($password1);
$password2 = mysql_real_escape_string($password2);
if ($password1 <> $password2){ echo "Your passwords do not match.";}
{
echo "your passwords do not match";
}
if (mysql_query(UPDATE ebsmembers SET password='$password1' WHERE username='$session[username]'))
{
echo "You have successfully changed your password.";
}
mysql_close($dbcon);
header("location:login.php");
?>
Again, any help would be massively appreciated as I have really struggled with making this work!
Many thanks,
Paul

Tweaked a few things that where errors or didn't make sense to me. Also switched to mysqli_*.
<?php
session_start();
if (!(isset($_SESSION['username']) || $_SESSION['username'] == ''))
{
header("location:login.php");
}
$dbcon = mysqli_connect('000.000.000.00', 'my_db_username', 'my_db_password', 'my_db_name') or die(mysqli_error($dbcon));
$password1 = mysqli_real_escape_string($dbcon, $_POST['newPassword']);
$password2 = mysqli_real_escape_string($dbcon, $_POST['confirmPassword']);
$username = mysqli_real_escape_string($dbcon, $_SESSION['username']);
if ($password1 <> $password2)
{
echo "your passwords do not match";
}
else if (mysqli_query($dbcon, "UPDATE ebsmembers SET password='$password1' WHERE username='$username'"))
{
echo "You have successfully changed your password.";
}
else
{
mysqli_error($dbcon);
}
mysqli_close($dbcon);
?>

Your use of the session is wrong. In your SQL query, it should be:
UPDATE ebsmembers SET password = '$password1' WHERE username= '$_SESSION[username]'
Also your syntax is very bad. It's missing quotes in several places. You should start with the PHP basics again before making your changes.

Query should be quoted:
if (mysql_query("UPDATE ebsmembers SET password='$password1' WHERE username='$_SESSION[username]'"))
Don't use mysql, it's deprecated. Use mysqli or PDO instead:
The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead
Don't store passwords in plain text. Use bcrypt encryption with password_hash() and password_verify() functions:
How do you use bcrypt for hashing passwords in PHP?

$password1 = $_POST['newPassword'];
$password2 = $_POST['confirmPassword'];
must be
$password1 = $_POST['InputPassword2'];
$password2 = $_POST['InputPassword3'];

you can use update statement for this purpose, create a same form with:
username(name=$name)
existing password(password=$pw1)
new password
submit
First select the current user name using sql select statement:
$my_qry ="select * from table_name where name= $name";
for updation use the statement:
$query = mysql_query("UPDATE table_name SET password='".$pw1."' WHERE name='".$name."'");
if(!$query)
{
mysql_error();
echo "hello";
}
use if else conditions for this, if the first select query is true then only the update query with work

Related

PHP Instert will not insert into Database

(so to begin I'm a high school student so not the greatest with the lingo so try your best to guide rather than tell if you can) When using insert to put data into my database from the website it appears to work but nothing appears in the database but no error codes.
I am using Mysqli, PHP, and Wampserver to run a local server and the website will not send data to the Database.
<?php
include 'connect.php';
include 'header.php';
?>
Sign Up<br>
<form method="post" action="">
Username: <input type="text" name="user_name"><br>
password: <input type="password" name="user_pass"><br>
password <Check: input type="password" name="user_pass_check"><br>
Email: <input type="text" name="user_email"><br>
<input type="submit" value="Register">
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$sql = "INSERT INTO users(user_name, user_pass, user_email) VALUES('".mysqli_real_escape_string($con, $_POST['user_name'])."', '".sha1($_POST['user_pass'])."', '".mysqli_real_escape_string($con, $_POST['user_email'])."', NOW(), 0)";
$result = mysqli_query($con, $sql);
if (!$result) {
echo 'Something went wrong';
echo mysqli_error($con);
} else {
echo "you have successfully registered. you can now <a href='signin.php'>sign in</a> and start posting";
}
}
}
include 'footer.php'?>
In my file used for connection
<?php
$host = 'localhost';
$user = 'root';
$pass = '';
$dbname = 'seqevents';
$con = new mysqli($host, $user, $pass, $dbname) or die("cannot connect");
session_start();
if (!isset($_SESSION['user_level'])) {
$_SESSION['user_level'] = 0;
}
I receive no error messages and nothing happens on the website it just reloads and gets rid of any input within the text boxes.
First the (likely) problem, then some other important pointers:
When you insert, you insert set 3 columns (user_name,user_pass,user_email) and then load 5 values into it (NOW() and 0) are extra, it has no clue where to place those values.
DO NOT USE MD5. If you're thinking "yeah, but my site isnt very interesting, why cares" read this line again. DO NOT USE MD5. Or sha1:
Never store passwords in clear text or using MD5/SHA1! Only store password hashes. Use PHP's password_hash() and password_verify() . If you're running a PHP version lower than 5.5 (which I really hope you aren't), you can use the password_compat library to get the same functionality. – Dharman
Use prepared statements. mysqli_real_escape_string is a good first step, but not adequite. Prepared statements secure the query for you. Bit more complex, a lot more secure.
I suggest removing $_SERVER['REQUEST_METHOD'] === 'POST'. What if you have two forms on your page? You're stuck. Instead, give your submit button a name like submitRegForm. Then you can do if( isset($_POST['submitRegForm']) )
DO NOT USE MD5 OR SHA1

PHP Login page is blank instead of echoing results

I'm trying to get a login page to work with PHP and Mysql. I've combed through my code, and don't know where I'm going wrong.
First I have a "login.php" page. Here's (what I believe) is the important code on that page:
<form id="login" action="redirect.php" method="post"> <!--This is the form for logging in.-->
<fieldset id="inputs">
<input type="hidden" name="ac" value="log"> <!--This value is a "random" value to post so that an if statement will be entered in select.php-->
<input id="username" name="username" type="text" placeholder="Username" autofocus required>
<input id="password" name="password" type="password" placeholder="Password" required>
</fieldset>
<fieldset id="actions">
<input type="submit" id="submit" value="Log in">
</fieldset>
From there you'll see that when submit is pressed it goes to "redirect.php" which has the following code:
<?php
include 'config.php';
$username = $_POST['username'];
$password = $_POST['password'];
function SignIn()
{
session_start(); //starting the session for user profile page
if(!empty($username)) //check to see if the username is empty or not from login.php
{
$query = mysqli_query($con, "SELECT * FROM employees where username = ".$username." AND password = ".$password) or die(mysql_error());
$row = mysqli_fetch_array($query) or die(mysql_error());
if(!empty($row['username']) AND !empty($row['password']))
{
$_SESSION['username'] = $row['password'];
echo "SUCCESSFULLY LOGGED IN!";
}
else
{
echo "YOU ENTERED WRONG ID OR PASSWORD...";
}
}
}
if(isset($_POST['submit']))
{
SignIn();
}
?>
You'll notice the config.php page is included... Here's the code for that (with my dbusername and dbpassword changed:
<?php
/* Database credentials. */
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'myusername');
define('DB_PASSWORD', 'mypassword');
define('DB_NAME', 'ropepart_techportal');
/* Attempt to connect to MySQL database */
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check connection
if($con === false){
die("ERROR: Could not connect. " . mysqli_connect_error());
}
?>
When I run through all of this on my webpage, I am greeted with a blank white page on the redirect.php. This is the case no matter what username/password combo I put in the login.php page. Whether or not the user actually exists in the database or not. I would expect to get at least a sentence at the top of the page that either says "SUCCESSFULLY LOGGED IN!" or "YOU ENTERED WRONG ID OR PASSWORD." Any idea where I'm going wrong?
You're not sending value for submit in post body.
Try adding :
<input type="submit" name="submit" id="submit" value="Log in">
Since you've checked isset($_POST['submit']) which since you're not sending evaluates to false , and SignIn() is never called
I agree with our friend here, you set id for input, but you need set name to be send during the request, but I strong recomend u change two things in your code
add this attr to input submit -> name="submit"
Instead of this
if(isset($_POST['submit']))
{
SignIn();
}
Use this
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
SignIn();
}
And don't do this on start of the code
$username = $_POST['username'];
$password = $_POST['password'];
Because when u try to access an array that is not defined the php can outputs an error, and for some security reasons this isn't recommend, so before set the variables, check it, like this:
if (isset($_POST['username']) {
$username = $_POST['username'];
}
Your intimidate problem is there is no scope resolution on your variables
$username = $_POST['username'];
$password = $_POST['password'];
function SignIn(){
//$username does not exist in this scope
Instead
function SignIn($username, $passwrd){
....
}
SignIn($username, $passwrd);
That said their is a bunch of other "stuff" that I would fix, give me a few minutes and I will post something on it. Now if you had error reporting on you would see something like this
Warning: undefined variable $username
Here you go (untested but it should be close)
<?php
//turn on error reporting for development
//note even this may not catch syntax errors if they happen in this file
error_reporting(-1);
ini_set('display_errors',1);
require_once 'config.php'; //should be require once for a config
session_start(); //starting the session for user profile page
$dashboard = 'http://localhost/dashboard'; //some location to send a user after login
if(!empty($_SESSION['username'])){
//user is already logged in
header('Location: '.$dashboard);
}
//array for error tracking
$errors = [];
//if(isset($_POST['submit']))
//by checking the below outside of this we are assuming post
// has already happend, so there is no need to check this
//it was similar in your original code.
//if post isn't set then username and password will be FALSE
//and it will be caught by the error checking for those anyway
$username = isset($_POST['username']) $_POST['username'] : false; //check if isset if not set a default
if(!$username) $errors[] = 'Please enter a username';
$password = isset($_POST['password']) $_POST['password'] : false;
if(!$password) $errors[] = 'Please enter a password';
if(count($errors)){
//return to the page with error messages
//I have no idea how you build the page or how it relates to this
//so I cant hellp you there
die(implode('<br>', $errors));
}else{
//use single quotes for SQL, which prevents accidentally putting a variable in it.
// '$password' is literally $password, but "$password" is the value of it
//look up only what you need (password)
//don't look up by the password, DB is case insensitive and
//and is not cryptologicalally secure way to compare hashes.
$stmt = mysqli_prepare($con, 'SELECT password FROM employees where username = ?');
//I don't use mysqli (for like 4 years, and I never used the procedural style)
//so I had to look this up, if it's not right sorry ;-/, this is so much harder then PDO
/* bind parameters for markers */
mysqli_stmt_bind_param($stmt, "s", $user);
/* execute query */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $hash);
//not sure this will work, sorry
//in the example it showed storing the results,
//so not sure if you have to do that.
$num_rows = mysqli_stmt_num_rows($stmt);
//check that one and only one row is returned
if(!$num_rows){
//User not found, again I have no idea how to display this for you
die('Username was incorrect, please try again.');
}else if($num_rows > 1){
//should never happen with unique usernames
// again I have no idea how to display this for you
//this can prevent some errors from allowing logins
//this is an error message you may not want to show in production code
die('Returned more then one user account.');
}
/* fetch value */
//because we did mysqli_stmt_bind_result($stmt, $hash)
//which is bind $hash to column 1, this populates that
//variable with the data from the first row
mysqli_stmt_fetch($stmt);
//bool password_verify ( string $password , string $hash )
//Aug1 $password is plaintext, Arg2 $hash is from the DB
if(password_verfy($password, $hash)){
$_SESSION['username'] = $row['username'];
//you had password here in your original code (another bug?)
//$_SESSION['username'] = $row['password'];
//user is already logged in
header('Location: '.$dashboard);
}else{
//Incorrect password, again I have no idea how to display this for you
die('Your password was incorrect, please try again.');
}
}
I ditched the function call, as you mentioned in the comments.
I decided to get rid of my SignIn() function entirely, as it seems to not be needed in this case
You can read about prepared statements here
http://php.net/manual/en/mysqli.prepare.php
As I mentioned in the code, I haven't used mysqli much in the last 4 years, and even then I never used the procedural style. I quit doing the procedural style when I switched from mysql to mysqli about 7 years ago. There may be better ways to do that in mysqli, I just copied the example on the PHP documentation site. With PDO it would just be this (which is so much more elegant):
$stmt = $PDO->prepare('SELECT * FROM employees where username = :username');
$stmt->execute([':username' => $username]);
$num_rows = $stmt->rowCount();
$pass = $stmt->fetchColumn(0);
And the above assumes you are using PHP's built in password functions, which you should.
So to create a password use password_hash.
http://php.net/manual/en/function.password-hash.php
And to check it use password_verfy.
http://php.net/manual/en/function.password-verify.php
SQL Injection
In your original code we could turn you query into this,
"SELECT * FROM employees where username = ".$_POST['username']." AND password = ".$_POST[password]"
This is equivalent to what you have. Without preparing it someone can enter " OR 1=1 in the password field. There are only 2 styles of quotes and it wouldn't take much to figure it out. You can also encode the quotes in some instances, so simply checking for quotes wont due. What this would do is make your query:
SELECT * FROM employees where username = "admin" AND password = "" OR 1=1
Now because 1 is always equal to one 1 and this is password OR 1 then it effectively bypasses the password. You should only pull the password from the DB and then check it in PHP. That would prevent all of this (even with the sql issues) because as an attacker I would still need the password to pass that check. For example.
SELECT password FROM employees where username = "" OR 1=1
...
//even with a hacked row from the DB I still don't have $_POST['password']
if($_POST['password'] == $row['password'])
A few other Attacks
For the username it's almost the same " OR 1=1 --. The -- is the start of a line comment in SQL. And, because you are not checking the number of returned results it would also log me in as probably the first user found.
SELECT * FROM employees where username = "" OR 1=1 -- AND password = "
However if even if you did (check the number of results) all I would need to add is LIMIT 1 " OR 1=1 LIMIT 1 -- to it. I would probably do it this way anyway, if I was a hacker.
SELECT * FROM employees where username = "" OR 1=1 LIMIT 1 -- AND password = "
Then to boot I could iterate thought all your users by using an offset.
SELECT * FROM employees where username = "" OR 1=1 LIMIT 0, 1 -- AND password = "
SELECT * FROM employees where username = "" OR 1=1 LIMIT 1, 1 -- AND password = "
SELECT * FROM employees where username = "" OR 1=1 LIMIT 2, 1 -- AND password = "
etc.
And then steal all their stuff, or pick one with administrative rights your site etc.
Problem with not encrypting passwords
One of the biggest problems (outside of the obvious ones) is that users are lazy and they tend to use the same passwords. So once I compromised and admin account or even if you show the old password when a user goes to change it. Whatever way I get it... I could try that password against their email, also in their account. And once I find the poor sucker that has the same email password, I could find any sites they use. Then use that common password (preferred as they wont even know) or now that I own their email account I can just reset the password if I need to, to gain access to things like their online banking accounts etc..
So as you can see this is not something we can allow to happen.
Even when just learning, we should try to learn to do it the proper way, or at least in a way that offers some minimal security.
Cheers.

How to check username and password matches the database values

I'm really sorry if the question looks silly. But I've been trying for days to check my username and password in the database matches what I'm typing in the html page... This is my Login form...
<form method="POST" action="Dashboard/Dashboard.php">
<div class="form-group md-form">
<!--<input type="email" class="form-control" id="email" value="" placeholder="Enter email address">-->
<i class="fa fa-user prefix grey-text"></i>
<input name="username" id="username" type="text" class="form-control" required>
<label for="defaultForm-email">Username</label>
</div>
<div class="form-group md-form">
<!--<input type="password" class="form-control" id="password" value="" placeholder="Enter password">-->
<i class="fa fa-lock prefix grey-text"></i>
<input name="password" id="password" type="password" class="form-control" required>
<label for="defaultForm-pass">Your password</label>
</div>
<div class="text-center">
<button type="reset" class="btn btn-amber btn-sm"><strong>Reset</strong></button>
<input type="submit" name="submit" id="submit" class="btn btn-green btn-sm" value="Sign in">
</div>
</form>
And this is the code(php) I'm using in Dashboard.php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$databaseName = "test";
$conn = mysqli_connect($servername, $username, $password, $databaseName);
$un = $_POST['username'];
$pw = $_POST['password'];
print $pass . "_" . $email;
$query = mysqli_query($conn, "SELECT log_username,log_password FROM login WHERE log_username='$un' AND log_password='$pw'");
$result_can = mysqli_query($conn, $query);
while ($row = mysql_fetch_assoc($result_can)) {
$check_username = $row['username'];
$check_password = $row['password'];
}
if ($un == $check_username && $pw == $check_password) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
?>
I really tried like thousands of times, but couldn't figure out where I went wrong... Can anyone please help me?
I know my code is open to SQL injection, but I don't care about it as this is a example I needed to show to my friends So neglect that part.
Stack Overflow is for "professional and enthusiast programmers." With respect, you've shown us code in your question that isn't even close to being worthy of either name. It's grossly insecure, and if you put it on the public internet, your site will be cracked by cybercriminals.
StackOverflow people don't have much of a sense of humor about bad security code. You get strong reactions to code like yours because, well, Equifax, and Ashley Madison, and Adobe, and all the rest of the places that have been cracked by cybercriminals. Why do we jump on you? Because we don't like cybercriminals and we don't want to make life easy for them. Friends don't let friends do bad password security. Friends don't show friends grossly insecure password-validation code.
What's wrong with your code? You're storing passwords as plain text, and you're vulnerable to SQL injection. I will address the first of these issues.
Fortunately, php has outstanding industry-leading facilities to do password security. Read about them here. http://php.net/manual/en/faq.passwords.php Use them. How do you handle passwords?
When a user registers on your site and first presents a password, you hash it, in your code running on your server, something like this.
$usersPassword = $_POST['password']);
$hash = password_hash( $usersPassword , PASSWORD_DEFAULT );
// you then store the username and the hash in your dbms.
// the column holding the hash should be VARCHAR(255) for future-proofing
// NEVER! store the plain text (unhashed) password in your database
When a user tries to log in, you do a query like this on your server:
SELECT log_password FROM log_user WHERE log_username = TheUsernameGiven
You then put the retrieved password into a variable named $hash.
You then use php's password_verify() function, again on your server, to check whether the password your would-be user just gave you matches the password in your database.
Finally, on your server you check whether the user's password needs to be rehashed, because the method you used previously to hash it has become obsolete.
$usersPassword = $_POST['password']);
$valid = password_verify ( $usersPassword, $hash );
if ( $valid ) {
if ( password_needs_rehash ( $hash, PASSWORD_DEFAULT ) ) {
$newHash = password_hash( $usersPassword, PASSWORD_DEFAULT );
/* UPDATE the user's row in `log_user` to store $newHash */
}
/* log the user in, have fun! */
}
else {
/* tell the would-be user the username/password combo is invalid */
}
This sequence is futureproof, because it can rehash passwords later if the old hashing method gets too easy for cybercreeps to crack. Many user accounts have lifetimes far longer than versions of packages like php.
For credentials like passwords to remain secret, you must use https, not http, to connect between browser and server. Otherwise cybercriminals can intercept the traffic from your user to your server and grab her password. It can be a pain in the xxx neck to rig up an https-enabled server, but it's a critical part of deploying a web application. (Services like Heroku allow you to test your apps with https easily.)
Several problems, some were mentioned by comments above.
Mixing mysql_* vs. mysqli_* API
You call the query with mysqli_query() but you try to fetch results with mysql_fetch_assoc(). You can't mix these different APIs. The mysql_* functions will not use the connection you opened with mysqli_connect(), and vice-versa. Pick one MySQL extension and stick with it.
Hint: Don't use mysql_* at all. It's deprecated, and has been removed from PHP 7.0+
Querying with conditions for both username and password
Just search for the username, and fetch the password. If you search for both, then the search will return zero rows, unless the correct password was used.
You don't want that. You want to avoid putting the plaintext password in the SQL query. Just search on the username, and fetch the stored password and then compare what you fetch to the user input password.
Uninitialized variables
If you fetch zero rows from your query, then $check_username and $check_password are never set. Then you compare those variables in your if statement. Not a fatal error, but bad style.
No password hashing
You appear to be comparing the user input, which I assume is plaintext, directly to what's stored in the database. You're Probably Storing Passwords Incorrectly.
Instead, when you store your password, use password_hash() first.
No query parameters
I know you said you don't care about your SQL injection vulnerability, but this is like being an electrician and saying you don't care that your electrical panel is stuffed with oily rags. Be sure to post your disregard for safety on your LinkedIn profile, so employers know who to avoid.
Recommended implementation
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // enable exceptions
$conn = new mysqli($servername, $mysql_username, $mysql_password, $databaseName);
$log_username = $_POST['username'];
$log_password = $_POST['password'];
$sql = "SELECT log_username, log_password_hash FROM login WHERE log_username=?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $log_username);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
if (password_verify($log_password, $row['log_password_hash'])) {
$message = "ok";
// header must be called before any other output
header("Location: Doctors.php");
exit();
}
}
$message = "No";
// header must be called before any other output
header("Location: Doctors.php");
There are several problems here, both in your code and in the thought process. Let's work our way down:
$un = $_POST['username'];
$pw = $_POST['password'];
print $pass . "_" . $email;
That print line should be giving you a warning. The variables $pass and $email do not exist. You should remove that line, unless what you were trying to do is to print $un and $pw instead.
$query = mysqli_query($conn, "SELECT log_username,log_password FROM login WHERE log_username='$un' AND log_password='$pw'");
There's no need to select both the username and password column. If there is a match, they will always be the same as $un and $pw, which you already have. You're only checking whether the username and password are correct or not, so selecting a single column is good enough. Preferably the user id, but only the username will be sufficient.
Keep in mind that -- assuming the query executes successfully -- $query will contain a mysqli_result object.
$result_can = mysqli_query($conn, $query);
This line needs to be removed. You have already executed your query and $query is its result, what you're doing here makes no sense and should be giving you a warning, or perhaps even a fatal error.
while ($row = mysql_fetch_assoc($result_can)) {
$check_username = $row['username'];
$check_password = $row['password'];
}
if ($un == $check_username && $pw == $check_password) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
You cannot mix mysql_* and mysqli_* functions. Using mysql_fetch_assoc() here should give you a fatal error. You should use mysqli_fetch_assoc() instead (on $query instead of $result_can), however:
Since you're only interested in whether or not there was any result at all, this whole section can be changed to:
if (mysqli_num_rows($query) > 0) {
$message = "ok";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
} else {
$message = "No";
echo "<script type='text/javascript'>alert('$message');</script>";
header("Location: Doctors.php");
}
This will pose other problems, because you cannot use header() to redirect the user after echo'ing your <script> tag (you will get a "headers already sent" error). If you want the Javascript alert, perform the redirect with Javascript as well. Also, that $message variable is rather useless, you might as well put the message directly into the alert:
if (mysqli_num_rows($query) > 0) {
echo "<script type='text/javascript'>alert('ok'); window.location.href='Doctors.php';</script>";
} else {
echo "<script type='text/javascript'>alert('No'); window.location.href='Doctors.php';</script>";
}
Once you fix all of these issues, you still have some thinking to do.
You should never store passwords in plain text in your database.
You may not care about SQL injection right now, but with your current query I can log in as any valid user (e.g. "admin") by typing their username as admin' AND 1 --, or if I just want access I can use a username of any' OR 1 -- and be logged in as the first user in your table. Look into prepared statements and how they work.
You have no error handling at all. You should add checks to see if the database connection was opened successfully, the query executed properly, the form was posted and the username/password fields were filled in and think about how you want to present a useful error message to the user.
The main lesson here should be: when you're developing and it doesn't work, always check the error logs to see if it contains any hints and turn on PHP's error reporting features so you can see what you did wrong right in your browser.

Anyone able to help me with this bug in a login form?

So, I have a login form which is having a bit of trouble. It keepsechoing Incorrect password, please try again. whenever I try and access the restricted page. I have had a fiddle on myself, but I have not been able to find out what is wrong. The code is as follows:
<?php
//MySQL Database connect;
include "databaselogin.php";
//Checks if there is a login cookie
if(isset($_COOKIE["ID_my_site"]))
//If there is a cookie, the user is directed to a restricted page
{
$emailaddress = $_COOKIE["ID_my_site"];
$pass = $_COOKIE["Key_my_site"];
$check = mysql_query("SELECT * FROM Users WHERE EmailAddress='$emailaddress'") or die(mysql_error());
while($info = mysql_fetch_array( $check )) {
if ($pass != $info["password1"]) {
}
else {
header("location: restricted.php");
}
}
}
if (isset($_POST["submit"])) { //If the form has been submitted
//Make sure they filled it all in
if(!$_POST["emailaddress"] | !$_POST["password1"]) {
echo("You did not fill in all the required fields.");
}
//Checks it against the database
if (!get_magic_quotes_gpc()) {
$_POST["emailaddress"] = addslashes($_POST["emailaddress"]);
}
$check = mysql_query("SELECT * FROM Users WHERE EmailAddress = '".$_POST["emailaddress"]."'") or die(mysql_error());
//Gives a message if the user doesn't exist
$check2 = mysql_num_rows($check);
if ($check2 == 0) {
echo ("The Email Address that you have entered is not in use, <a href='register.php'>click here</a> to register");
}
while($info = mysql_fetch_array( $check )) {
$_POST["password1"] = stripslashes($_POST["password1"]);
$info["Password"] = stripslashes($info["Password"]);
$_POST["password1"] = sha1($_POST["password1"]);
//Gives an error is the password is wrong
if ($_POST["password1"] != $info["Password"]) {
echo("Incorrect password, please try again.");
}
else {
//If the login is ok, a cookie is added
$_POST["EmailAddress"] = stripslashes($_POST["EmailAddress"]);
$hour = time() + 3600;
setcookie(ID_my_site, $_POST["emailaddress"], $hour);
setcookie(Key_my_site, $_POST["password1"], $hour);
//Then they are redirected to a restricted area
header("location: restricted.php");
}
}
}
else {
//If they are not logged in
?>
<form action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
<table border="0">
<tr><td colspan=2><h1>Login</h1></td></tr>
<tr><td>Email Address:</td><td>
<input type="text" name="emailaddress" maxlength="40" placeholder="Email Address">
</td></tr>
<tr><td>Password:</td><td>
<input type="password" name="password1" maxlength="12" Placeholder="Password">
</td></tr>
<tr><td colspan="2" align="right">
<input type="submit" name="submit" value="Login">
</td></tr>
</table>
</form>
<?php
}
?>
All help will be massively appreciated.
There are a couple of issues. First, mysql_query is a deprecated PHP function and should be replaced with mysqli_query. All functions in your code should use the mysqli prefix instead of mysql (so mysql_fetch_assoc should be changed to mysqli_fetch_assoc). This function also takes a parameter providing a connection to the database, which is done with mysqli_connect. So your code should have something like this:
$con = mysqli_connect($username, $password, $host, $db); // Fill in the variables with correct values
$check = mysqli_query($con, "SELECT * FROM Users WHERE EmailAddress='$emailaddress'");
$con only needs to be set once and can be used in other query calls in your code.
First of all the way you store your credentials in cookies is very dangerous. Anyone who has access to your computer or to your network if you're not using ssl can steal your cookies and log in to your account.
Secondly your problem lies in
while($info = mysql_fetch_array( $check )) {
this is an infinite loop. you should only call this once.
Your overall code could use some improvements such as:
update mysql to mysqli or PDO
use prepared statements
optimize code for speed (use || instead of |)
use a stronger hashing algorithm
Leave a comment if you want a more in depth instruction to improve your code
Hope this helped
Improvements
this is a great article about PDO. But PDO is object based and since you're new to PHP and i don't know your skill level you can better use mysqli for now. There're plenty of articles available on how you can do this.
PDO
in your code you use
if(!$_POST["emailaddress"] | !$_POST["password1"]) {
but if you use || instead of | the if condition skips the second argument if the first already failed.
You use sha1 for hashing your passwords. But this algorithm is a bad practice. You should use Bcrypt or at least use an individual salt for each password you encrypt with sha1 and store that next to the password in the database
SHA1 not safe anymore
You never store the user info in a session to retain the login on next requests, the way you're implementing it is called a remember me function and is considered hard to implement safely. it is easier to work with sessions first and if you really need it cookies later.
If you're using sessions you should also check if the session_id hasn't been set by an attacker in the clients browser. You can do this by setting a random cookie such as init
and when this is not set you call
session_regenerate_id();
You store both the email and the hashed password in a cookie. this can be very dangerous. You shouldn't store the password even if it is hashed in an cookie. The best practice is to hash a randomly created string of characters with a high entropy and store only that in the cookie and in the database. When the user logged in once with that cookie you should refresh the cookie with a new hash.
To fix your error you should remove the while loop around the mysql_fetch_array($check)
Tips for in the future
Your code looks a lot more organized if you start to learn to work with PHP objects. This can also make your project a lot easier to work with.
I don't know if you're going to use this code in a production website because I highly recommend against that. You can better use a safe and sound solution that somebody with more experience has created and when you have more experience you can start building your own.

PHP/MySQL Login Not Working

Can anyone tell me why this simple PHP/MySQL login code is always showing "Wrong username or password" even if I type in the correct username/pass combo? I have spent a ton of time trying to figure this out.
<?php
// Database Connection
mysql_connect("IP", "charlesfries", "Password") or die(mysql_error());
mysql_select_db("charlesfriessdatabase") or die(mysql_error());
// Variables
$username = $_POST["username"];
$password = $_POST["password"];
$result = mysql_query("SELECT * FROM accounts WHERE username = '$username' and password = '$password'");
// Success
$count = mysql_num_rows($result);
if ($count == 1) // Checks for Single Record of Given Username & Password
{
session_register("username"); // Registers Username Key in Session
session_register("password"); // Registers Password Key in Session
header("location:http://charliefries.tk/");
}
// Failure
else
{
echo "Wrong Username or Password";
}
?>
Also, please don't tell me my code is injectable. I know it is.
Here is my form code:
<form action="signinprocess.php" method="post"> <!-- Sign In Process -->
Username: <input type="text" name="username" style="width:150">
<br />
Password: <input type="password" name="password" style="width:153">
<br />
<br />
<input type="submit" value="Sign In">
</form>
Try LIMIT 1 in SELECT to ensure you only have 1 row.
There are a few "bad ideas" in your code:
Don't use mysql_* for new projects. This is outdated. Switch to mysqli_* http://php.net/manual/en/book.mysqli.php
Selecting by username and password is not always a good idea. In most cases, it is better to search for the username and check, if the password is correct. With prepared statements, you will get something like this
SELECT * FROM accounts WHERE username=?
In the next step, you can check, if your password is the same as in the database, e. g. with a if statement $_POST['password']==$dataFromDB['password'].
Currently you are saving the password in plain text. This is a really bad idea. Take a look at bcrypt. See How do you use bcrypt for hashing passwords in PHP?
session_register is outdated. Use something like
$_SESSION['username']=$dataFromDB['username']
As I see, the problem is in the (not existing) LIMIT. Hope these hints will help you anyway.

Categories