I've created a code to change a password. Now it seem contain an error.
When I fill in the form to change password, and click save the error message:
You forgot enter your userid!
Please try again.
I really don’t know what the error message means. Please guys. Help me fix it.
Here's is the code:
<?php # change password.php
//set the page title and include the html header.
$page_title = 'Change Your Password';
//include('templates/header.inc');
if(isset($_POST['submit'])){//handle the form
require_once('connectioncomplaint.php');//connect to the db.
//include "connectioncomplaint.php";
//create a function for escaping the data.
function escape_data($data){
global $dbc;//need the connection.
if(ini_get('magic_quotes_gpc')){
$data=stripslashes($data);
}
return mysql_real_escape_string($data);
}//end function
$message=NULL;//create the empty new variable.
//check for a username
if(empty($_POST['userid'])){
$u=FALSE;
$message .='<p> You forgot enter your userid!</p>';
}else{
$u=escape_data($_POST['userid']);
}
//check for existing password
if(empty($_POST['password'])){
$p=FALSE;
$message .='<p>You forgot to enter your existing password!</p>';
}else{
$p=escape_data($_POST['password']);
}
//check for a password and match againts the comfirmed password.
if(empty($_POST['password1'])) {
$np=FALSE;
$message .='<p> you forgot to enter your new password!</p>';
}else{
if($_POST['password1'] == $_POST['password2']){
$np=escape_data($_POST['password1']);
}else{
$np=FALSE;
$message .='<p> your new password did not match the confirmed new password!</p>';
}
}
if($u && $p && $np){//if everything's ok.
$query="SELECT userid FROM access WHERE (userid='$u' AND password=PASSWORD('$p'))";
$result=#mysql_query($query);
$num=mysql_num_rows($result);
if($num == 1){
$row=mysql_fetch_array($result, MYSQL_NUM);
//make the query
$query="UPDATE access SET password=PASSWORD('$np') WHERE userid=$row[0]";
$result=#mysql_query($query);//run the query.
if(mysql_affected_rows() == 1) {//if it run ok.
//send an email,if desired.
echo '<p><b>your password has been changed.</b></p>';
//include('templates/footer.inc');//include the HTML footer.
exit();//quit the script.
}else{//if it did not run OK.
$message= '<p>Your password could not be change due to a system error.We apolpgize for any inconvenience.</p><p>' .mysql_error() .'</p>';
}
}else{
$message= '<p> Your username and password do not match our records.</p>';
}
mysql_close();//close the database connection.
}else{
$message .='<p>Please try again.</p>';
}
}//end of the submit conditional.
//print the error message if there is one.
if(isset($message)){
echo'<font color="red">' , $message, '</font>';
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
Please don't store the actual password in the database. Create a hash of the password and store it. When a user logs in, hash the incoming password and check if it matches the hashed password for the user. See http://phpsec.org/articles/2005/password-hashing.html for more info.
Also, it would be more secure to store the userid in the session and retrieve it from there rather than getting it from the form. Even if the input is hidden on the page there are any number of ways that it could be substituted. It leaves you with a small hole in the application where, if one user knows another user's id and password, they can change it in an undetectable fashion. That is, the password could be changed despite the fact that you have no record of that user having logged in. Even when getting the user id from the form (or the url), always check that the data they are operating on is their own, not someone else's unless, of course, they are a user with sufficient privileges.
It means that you didn't send along userid with your POST parameters. Presumably, your form didn't include an element with name userid. The error comes from this line:
if(empty($_POST['userid'])){
That error is displayed because of this test :
if(empty($_POST['userid'])){
$u=FALSE;
$message .='<p> You forgot enter your userid!</p>';
}
Which means the server doesn't receive a userid field from the form.
I'm guessing you should make sure there is such a field in your form -- and it'll have to contain the userid of the user for which you want to change the password.
Considering you probably don't want that field to be displayed, though, you'll use a hidden input :
<input type="hidden" name="userid"
value="<?php echo htmlspecialchars(HERE THE USERID); ?>" />
According to your code it means that the userid POST variable was empty. Verify the name of the field you use for it.
Related
So I'm very new to PHP and I'm still learning. I just learned about superglobals and using POST, GET, SESSION, COOKIES etc.
To test my current knowledge, I made a simple log in code. Where there are two pages, one for logging in, the other is the destination that can only be reached by logged in users. It's very simple, there is only one password "test pass" and it's checked through an if-statement. The username can be anything the user wants. I will obviously add more functionality to this project, like a sign up page, account info changing settings etc. But I can't do that without having my main code being solid. So my question is, security-wise, is this code okay? What would you do differently, and if there are non-security issues, I would also like to know.
Login Page:
<form method="post">
Username: <br>
<input type="text" name="user"> <br>
Password: <br>
<input type="password" name="pass"> <br>
<button type="submit" name="signin">Sign In</button>
</form>
<?php
session_start();
if (isset($_GET['logged']) && $_GET['logged'] == 'false'){
session_destroy();
header("Location: login.php");
}
if (isset($_POST['signin'])){ //form was submitted
//username check
if (!empty($_POST['user'])){ //username entered
$_SESSION['user'] = htmlspecialchars($_POST['user']);
} else { //no username entered
echo "You must enter your username!";
}
//password check
if (!empty($_POST['pass'])){ // a password was entered
if ($_POST['pass'] == 'testpass' && !empty($_POST['user'])){ // the password was correct and a username was entered
$_SESSION['logged'] = true; //user is logged in
header("Location: loggedin.php");
} else { // incorrect pass
echo "Incorrect Password!";
}
} else { //no pass entered
echo "You must enter a password!";
}
}
?>
Logged in page:
<html>
<head>
<?php session_start();
if (!$_SESSION['logged']){
header("Location: login.php");
} ?>
<title>Welcome <?php echo $_SESSION['user'] . "!";?></title>
</head>
<body>
Sign Out
</body>
</html>
It is okay for single user. You can improve security by adding md5() function.
eg: $_POST['pass']=md5('testpass'); and $_SESSION['user']=md5($_POST['user']);
If you want code for multiple user. Add mysql (database).
Are you going to be using a database to store users and other data? It'd be hard to evaluate the security of this if you're later going to be using a database.
In that case, you'd need to use prepared statements when querying the database and hashing when storing the passwords like Fred said. Prepared statements add protection against SQL injections which are very important to keep under control.
Another form of injection you need to worry about is script injection, or cross-site scripting (XSS). This is when you print user input back. You have added some protection for this using htmlspecialchars() on $_SESSION['user'] but you can do more, look more into it.
Problem has been solved
I have created a form that processes the changing of user information from the admin side e.g. the admin changes a user's username and/or email. I am having trouble processing multiple queries.
For example, if the admin changes the username, the query works. If the admin changes the email address, the query works. But if the admin changes the username and email at the same time through the form then only the username changes.
Any ideas? I will submit my code but I will change variables for security reasons etc. Also, anything in capitals has been changed for security reasons. The code is all correct for each individual function because as I said, if I ONLY change the email, it works and actually changes. But if I change the username AND email, only the username will change despite the fact the email query runs and it echo's the email has been changed!
Also, it is worth noting that all of the fields e.g. username field and email field are part of one form that submits to one page.
if (isset($_POST['SUBMIT_BUTTON_PRESSED'])) {
//Gather all inputs from the form and sanitise it.
//REMOVED FOR SECURITY REASONS.
if($USERNAME_NEW != "") {
if($USERNAME_NEW == $CURRENT_USERNAME) {
echo "You have entered the username you are already using. Please enter a different username.";
} else {
$CHECK_USERNAME = "SELECT USERNAME_ROW FROM USERS_TABLE WHERE username='$USERNAME_NEW'";
$RUN_QUERY = mysqli_query($CONNECTION INFO, $CHECK_USERNAME);
$RESULT = mysqli_num_rows($RUN_QUERY);
if($RESULT > 0) {
echo "That username already exists. You cannot use that username again. Please enter another username.";
} else {
$editing_username = true;
$USERNAME = $NEW_USERNAME; //NOT NEEDED BUT IT STILL WORKS
$THE_SQL_QUERY = "UPDATE USER_TABLE SET username='$USERNAME' WHERE username='$ORIGINAL USERNAME'";
$RUN_THIS_QUERY= mysqli_query($CONNECTION INFO, $THE_SQL_QUERY);
echo "The user's username has been changed to: ". $USERNAME;
}
}
}
if($EMAIL != "") {
if($EMAIL == $CURRENT_EMAIL) {
echo "You have entered the same email address to the one you are already using. Please enter a different email address.";
} else {
$CHECK_EMAIL = "SELECT USERS_EMAIL FROM USER_TABLE WHERE username='$USER'";
$CHECK_EMAIL_QUERY = mysqli_query($CONNECTION_INFO, $CHECK_EMAIL);
$RESULT = mysqli_num_rows($CHECK_EMAIL_QUERY);
if($RESULT > 0) {
echo "That email already exists. You cannot use that username again. Please enter another username.";
} else {
$editing_email = true;
$THE_NEW_EMAIL = $FINAL_EMAIL_THING; // AGAIN NOT NEEDED BUT STILL WORKS
$THE_SQL= "UPDATE USER_TABLE SET USER_EMAIL='$EMAIL' WHERE username='$USER' LIMIT 1"; // REMOVED THE LIMIT 1, STILL DOESN'T WORK
$RUN_THIS_QUERY = mysqli_query($CONNECTION, $THE_SQL);
if($RUN_THIS_QUERY) {
echo "The user's email has been changed."; // EVEN WHEN BOTH FIELDS ARE SUBMITTED THIS WORKS SO THE QUERY IS RUNNING BUT THE EMAIL DOESN'T CHANGE
}
}
}
}
Thanks for the help! Also, no un-witty remarks about how my question is structured etc. because I don't care to be honest. I just want this code working to be honest because I've been working on it for a while. This may be something simple or I might be using the wrong approach for this type of form submission.
Remember: THIS CODE DOES WORK WHEN I SUBMIT EACH FIELD SEPARATELY!
Its very hard to figure out as you are not producing the real code.
I think you have missed something here.
As you are using USER_NAME as key in the SQL's, make sure that you are using the updated username in the second sets of SQL (to update the email) as they are already replaced by the first SQL.
And there is no security risk while showing your codes snippets to someone else. Hide only the username/passwords or Identities. :)
I'm trying to create a webpage with users and information that can only be accessed by registered users. Is it possible to limit the files an unregistered user can see? If so, how? I already have a MySQL database with a connection in index.php. Here's what I have so far:
<head></head>
<body>
<h3>Signup Here:</h3>
<form method="post" action="userindex.php">
Please enter user name: <input type="text" name="username" value="" /><br />
Please enter password: <input type="password" name="password" value="" />
<br />
<input type="submit" value="Submit"/>
</form>
</body>
<?php
include ("dbroutines.php");
if (isset($_POST['username'])) {
if ($_POST['username']>'' && $_POST['password']>'' ) {
$q="insert into users (Name, Password ) values ('".$_POST['username']."', '".$_POST['password']."')";
echo 'query='.$q;
$conn=db_connect();
$result=$conn->query($q);
echo '<br />xxx'.$conn->error."xxx";
unset($_POST['username']);
unset($_POST['password']);
} else {
echo 'Please enter both username AND password!';
}
}
$q="select Name, Password from users";
$conn=db_connect();
$result=$conn->query($q);
echo 'xxx'.$conn->error."xxx";
if ($result){
echo '<hr />';
for ($count=0; $row=$result->fetch_row(); ++$count ) {
echo $count." Name=".$row[0]." password=".$row[1].'<br />';
}
echo '<b style="color:red;">there are '.$count.' users in your database!'.'</b><hr />';
}
From this, can you specify what kind of user gets access to certain files like the userindex.php?
I think verifying user is not the fool proof solution . You have to keep a token in the Session to remember that this user is registered user. You have to create a common php page , called Security.php where you will put the following code , because a smart user can directly type the URL and reach to your confidential pages. You need to include this page at the top of each php page you want to secure.
if (!isset($_SESSION['AuthId'])) {
header('Location:Login.php');
exit;
}
Yes. Query your database for someone with the given username and password using a query that would look something like this:
select * from users where Name = 'john.doe' and Password = 'hunter2' limit 1
If it yields any rows, the user exists, and you should let them in. If there are no rows, then that combination of username and password is invalid and you should not let them in.
That's the basics, but if you're actually going to put this into production, you'll want to make a few more changes:
Escape the data you're putting in the query appropriately or use prepared queries. As is, your code is vulnerable to an SQL injection attack. Say, for example, I tried to create an account with an apostrophe in the username or password. Your code would break. This could be leveraged for malicious means, too, so you really should patch that up.
The simplest way to patch it up would be to escape everything before you put it into the query, using, say, mysql_real_escape_string. That'll probably work, but even better (since the whole mysql_ family of functions is deprecated) would be to use prepared queries and PDO, as I've shown below.
Hash and salt your passwords so a database compromise (which could happen rather easily if the above vulnerability is left unpatched) will not reveal all the passwords.
Your code might then look like this:
// You'd probably want to put these in a separate configuration file.
$db = new PDO('mysql:dbname=test', 'my_mysql_user', 'hunter2');
// Make any errors throw an exception.
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = $db->prepare('select * from users where Name = :name limit 1');
$query->bindValue(":name", $_POST['username'], PDO::PARAM_STR);
$row = $query->fetch(PDO::FETCH_ASSOC);
if($row === FALSE) {
// User not in the database; don't let them in.
}
$calculatedHash = hash("sha512", $row['PasswordSalt'] . $_POST['password']);
if($calculatedHash === $row['PasswordHash']) {
// Password's right. Let them in.
}else{
// Password's wrong. Keep them out.
}
Further improvements would be to use, say, bcrypt rather than salted SHA-512.
You can put the one extra field in the loggin table name 'Role'.
Each login time. Check if it is Master user,then It can access the more access.
If it is extra user then limited access.
You got my point? Or any Query?
I am creating a forgotten password page and will be emailing a temporary password to the user so they can log in and reset their password.
What should I take into account when creating the password, what is the best method.
An idea I had is something like: $temporarypassword = sha1($_SERVER['REMOTE_ADDR'])
In an attempt to only allow them to login from the ip address where they requested the temp password. What is the best way to do this??
Code so far:
if(strpos($_SERVER['HTTP_REFERER'],'domain.com') && ($_POST['forgotpasstoken'] == sha1($_SESSION['token'].'forgotpassword'))){
if(isset($_POST['forgotemail']) && !empty($_POST['forgotemail'])){
$email = mysql_escape_string(trim($_POST['forgotemail']));
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE){
echo '<div class="error">Please enter a valid email address.</div>';
} else {
$sql = "SELECT email FROM users WHERE email = '$email' LIMIT 1";
$res = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($res) > 0) {
//If email/user exists
$temporarypassword = sha1($_SERVER['REMOTE_ADDR'])
//EMAIL PASSWORD HERE
echo '<div class="success">A temporary recovery password has been emailed to you.</div>';
//If email/user exits
} else {
echo '<div class="error">This email is not registered.</div>';
}
}
} else {
echo '<div class="error">Please enter an email address.</div>';
}
}
Use just a random string: it's more than likely that user tries to log in from e.g. iPhone, fails, requests a new password, and only opens the link when he's at his home PC. IPs are different, device is different, everything's different.
If you're emailing the password, there is no way to make it fully secure. Email is transmitted in plain text. And like alf said, the user may reset the password from a different IP address than the one they requested it from.
One option would be to create a random string, then display half of it on the password reset page (after the reset request is made) and half of the string in the email. Then require the user to enter both halves in a form before letting them choose a new password.
Well, I am working on a new project which has a login page. The Error: I am unable to retrieve password from the form using $_POST method.
The Form Code:
<form action="loginsub.php" method="post">
<input type="password" name="pass" id="pass"/><br/>
<input type="submit" value="Go!"/>
</form>
The Code in loginsub.php
<? echo $_POST['pass']; ?>
I have also tried this method using text in place of password and it works. But what is the problem with the password? When I fill in the form and then submit it, the next page displays nothing!
Okay, Now, It's working! Thank you all, The Real Problem was: I want to take in password from a login form and then using mysql_query (php) want to find out if the username and password combination is there or not. If I am not wrong, the code for it is:
require_once('dbconfig.php');
$username = $_POST['username'];
$pass = $_POST['pass'];
$dbc = mysql_connect($dbserver,$dbuser,$dbpassword);
mysql_select_db('hello');
$query = "SELECT * FROM users WHERE username = '$username' AND password = PASSWORD('$pass')";
$result = mysql_query($query);
$row = mysql_num_rows($result);
if ($row == 1)
{ echo "User Name and Password are Correct"; }
else
{ echo "Error! Username and Password is Wrong!"; }
Is the code right? When I execute it, enter correct username and password (which exists in the database, I get the InCorrect Message, but again when I enter wrong username and password, I still get InCorrect message. Why?
I take you don't really want to print the password in your application? Anyway, it should be in your $_POST array - could you paste the output of putting
var_dump( $_POST );
in the page your submitting to?