How to check if a row has been updated? [duplicate] - php

This question already has answers here:
mysqli_affected_rows in PHP insert
(3 answers)
Closed 6 years ago.
I'm working with PHP and mysqli, what the program is doing is that it is asking for a reset code and email address if the email add and reset code are found in the database it sets the password,this part of the function is working,
I need help with this part: what I need to do is tell the user if the password was set or not so if the update was successful or not.
What I'm working on:
$uinsert = "UPDATE member SET password = '$password' WHERE emailadd = '$emailadd' AND resetCode = '$resetcode'";
$update = mysqli_query($mysqli, $uinsert) or die(mysqli_error($mysqli));
if(mysqli_affected_rows($update) == 1 ){ //ifnum
header("location: ../index.php"); // Redirecting To Other Page
}
else{
echo "<script> alert('Incorrect code, try again!');</script>";
}
Note: $mysqli is my connection string

"#Fred-ii- Thank you so much that works! – Coffee coder 58 secs ago"
Use if(mysqli_affected_rows($mysqli) >0 ) or no comparison at all.
Sidenote: ==1 is only comparing for 1, as opposed to >0 which you may be trying to update more than one row. However and on the rare occasion, >0 is required where this has also happened to me before; that is the reason of my answer.
affected_rows() uses the connection, not the one for the query.
http://php.net/manual/en/mysqli.affected-rows.php
Plus, if you're storing plain text passwords, use password_hash() since it's much safer:
http://php.net/manual/en/function.password-hash.php
Sidenote: If you do decide to move over to that function, make sure that you do not manipulate the password at all. Hashing/verifying it takes care of that and you may be doing more harm than good in doing so and limiting passwords.
I.e.: A valid password of test'123 would be interpreted as test\'123 and rendering FALSE when using real_escape_string() for example.
Or you may still be using hash_hmac as per your other question Comparing/check if correct Password from mysqli database [hash_hmac]
and a prepared statement:
https://en.wikipedia.org/wiki/Prepared_statement
It is also best to add exit; after header. Otherwise, your code may want to continue to execute.
header("location: ../index.php");
exit;

Change the parameter of mysqli_affected_rows(), the parameters must be the mysql connection
mysqli_affected_rows($update)
to
mysqli_affected_rows($mysqli)
Please see this reference
https://www.w3schools.com/php/func_mysqli_affected_rows.asp

if (mysqli_affected_rows($mysqli) == 1 ) {
Because mysqli_affected_rows() does not use the query $update as its parameter, it uses the connection variable: $mysqli

pass your mysqli connection object ($connection) to mysqli_affected_rows(connection_object) to check affected rows.
connection_object is like - $con=mysqli_connect("localhost","bd_user","db_password","your_db_name");
So , code will be
if(mysqli_affected_rows($con)== 1 ){
header("location: ../index.php");
}

Related

PHP password_verify false negative [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
Background -
I have spent the last hour or so looking through various posts sites and so on to see why my password checking function has suddenly stopped working.
Every time I try to use it, it returns false, including when the inputted password is correct.
I have echoed my input and my hash, both of which match fine (by comparing the hash in the table to the one echoed).
However, when these variables are put through password_verify, it returns false 100% of the time.
What do I think is wrong? - Based on a post from an external site, I think this is due to the way that my hashedPassword variable is being parsed. When is compares the two, something goes wrong in the variable type and returns false.
What does my code and database look like? -
users table. Contains other columns.
userId | username | password
----------------------------
1 | example | temp1
Class containing the password checker function. (Have trimmed away try/catch)
public function checkPasswordCorrect($username, $password) { // Returns true is the entered password is correct and false if it isn't.
// This creates a mysqli context to run the connection through.
$mysqli = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbPlusPlus);
// If there is an error connecting to the database, it will be printed and the process will close.
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$sql = "SELECT password FROM users WHERE username='$username'";
$result = $mysqli->query($sql);
$row = $result->fetch_array(MYSQLI_ASSOC);
$hashedPassword = $row["password"];
$mysqli->close();
echo $password."<br>".$hashedPassword."<br>"; // The input is correct and the hash matches that in the table.
// We return a value of true or false, depending on the outcome of the verification.
if(password_verify($password, $hashedPassword)) {
echo "return true";
return true;
}
else {
echo "return false";
return false;
}
}
By echoing $hashedPassword just before using password_verify, the hash matches by manually checking it, as you can see by the output below.
temp0022
$2y$10$9TgjJzSaqOB
return false
What am I asking? -
Is there a better way of checking password inputs, more specifically, the way I'm pulling the information from the table (there must be some simpler way of doing this).
Is the variable parsing to blame? Is there any documentation or articles available for this topic that I haven't seen?
What am I aware of? - My usage of mysqli is shocking, I'm new to it. I am also aware that there are similar answers out there, but seem to be down to some kind of syntax error more than anything else.
Thank you for taking the time to help! :D
For all of those of you who are worried that I'm going to be hit by SQL injection attacks: I have since modified this example code
massively and am using prepared, statements. Thank you for your
concern :)
Check your table structure. Your hash field needs to be of length 60 (for PASSWORD_BCRYPT) or 255 (for PASSWORD_DEFAULT) (ref) to save the whole hash. What you got from the database is 18 characters long. You probably have it as VARCHAR(18), so it's getting truncated upon saving, which is why you're not getting a match.
Edit: Added length for the PASSWORD_DEFAULT algorithm. Thanks #Don'tPanic.

Issue with PHP and Mysql

Good evening everyone, I'm having issues with my below code, Variable $uname is declared from a http post but for some reason the print out the the err log stays blank where it should show the results of the MySQL query
Field in table is called firstname (no caps)
$da= mysqli_query($c,
"SELECT * FROM users WHERE username='".$uname."'") or die(mysqli_error($c));
while ($row = mysqli_fetch_assoc($da)) {
error_log("User $Uname: match.");
error_log("FN : ".$row['firstname']."");
}
Any ideas ?
Add a message to tell you if no results were found by the query.
Since there can be only one user with a given username (I assume), you don't need a while loop. Just fetch that one row.
$row = mysqli_fetch_assoc($da));
if ($row) {
error_log("User $uname: match.");
error_log("FN : ".$row['firstname']."");
} else {
error_log("User $uname: no match.");
}
You also had a typo in your echo statement, $Uname should have been $uname.
First of all use a prepared statement: for security reasons you should never trust user inputs, prepared statements do the escaping for you.
Other than that I only see two reasons why nothing is logged:
error reporting is turned off ( this seems unlikely since you expect to see something in there)
the query is returning an empty result set and the while loop is skipped
try to print $uname or the full query and execute it

PHP : How to select another column

I have 3 columns in my table username, password and element. The value of element is 1. So I created a webpage If user insert the correct username and password I want my PHP to check that If element = 1 then do something I want and change element to 0. But If it is 0 so PHP do nothing. My problem is it's display white screen.
<?php
require_once("function/func_connect.php");
require_once("function/func_check.php");
require_once("function/websend.php");
$objLogin = checkPassword($_POST['user_name'],$_POST['user_password'],$Cfg["table"]["user"]);
if($objLogin == false)
{
include("state/login_failed.html");
exit();
}
if($objLogin == true)
{
// I think the problem cause here How do I fix?
mysql_query("SELECT element FROM authme WHERE username = $_POST['user_name']");
echo "success";
}
mysql_close();
?>
Thank you and sorry for my bad english.
Your basic error is you are not wrapping your string value in quotes.
mysql_query("SELECT element FROM authme WHERE username = $_POST['user_name']");
should be
mysql_query("SELECT element FROM authme WHERE username = '$_POST['user_name']'");
But, just as important, you are wide open to SQL injections. You need to fix that ASAP.
You also need to turn on error reporting so you can see your errors instead of getting just a white screen.
FYI, you shouldn't use mysql_* functions in new code. They are no longer maintained and are officially deprecated. See the red box? Learn about prepared statements instead, and use PDO or MySQLi - this article will help you decide which. If you choose PDO, here is a good tutorial.

PHP MySQL SELECT Query only returning resources

I'm currently working on building a download platform in which a user receives a random code and uses it to access an mp3 for download for up to three downloads. I generated a list of random codes using Python and imported them into a SQL table with an empty column for an associated email addresses and a default 0 for the use count. I wrote the following PHP script in order to associate an email with a certain code and add to the count so a download can be accessed up to three times.
$email = $_POST["email"];
$email = stripslashes($email);
$uniqueCode = $_POST["uniqueCode"];
$uniqueCode = stripslashes($uniqueCode);
// check that all fields are filled
if($uniqueCode=="" || $email=="")
apologize("Please fill out all fields.");
// check to make sure that the e-mail is valid
if (verifyEmail($email) == FALSE)
apologize("Please enter a valid e-mail address.");
// check if uniqueCode input is alphanumeric
if (verifyCode($uniqueCode) == FALSE)
apologize("Download codes are alphanumeric.");
// check to see if unique code is correct
$sql = mysql_query("SELECT * FROM wd009 where uniqueCode='$uniqueCode'");
$result = mysql_fetch_array($sql);
if($sql==FALSE)
{
apologize("Your download code is invalid. Please try again");
}
// only allow users with less than 3 downloads to proceed
else if ($result['count'] <= 3) {
if ($result['email'] == ""){
mysql_query("UPDATE wd009 SET email='$email', count=1 WHERE uniqueCode='$uniqueCode'");
apologize("added email");
}
else if ($result['email'] != $email)
apologize("different email from record!!");
else if ($result['email'] == $email){
mysql_query("UPDATE wd009 SET count=count+1 WHERE uniqueCode='$uniqueCode'");
apologize("updated the count!");
}
else
apologize("Your download code is used up!");
Obviously I use some functions in the above that aren't included in the code but I've checked all of them and none of them should interfere with the MySQL query. It may be of note that apologize() exits immediately after apologizing. When I input a correct code into the form, it works correctly and updates the SQL database. However, as long as the download code input is alphanumeric, the form will accept it even though the string definitely does not match any in the table. Namely, mysql_query returns a resource no matter the input. I've checked the database connection but since the table is correctly updated when the download code is correct, that doesn't seem to be the problem.
I've tried debugging this every way I could think of and am genuinely befuddled. Any help you could offer would be greatly appreciated!
As you can see in the manual, mysql_query always returns a resource for a valid query so you need to change your logic and count the number of rows it returns, not the result of mysql_query.
Apart from that, mysql_query, is deprecated and you should use mysqli or PDO.
You can count the number of rows with the - equally deprecated - mysql_num_rows function. 0 rows would be no valid code in your case.
This
if($sql==FALSE)
should probably be something like
if(mysql_num_rows($sql) == 0)
Edit: I agree, mysqli or PDO is preferred now.
The issue probably is this line:
if($sql==FALSE)
{
apologize("Your download code is invalid. Please try again");
}
Since the sql is a string it is accepting is as true and passing it as valid. One thing you also might like to do to avoid sql injection is use parameters instead of directly injecting user input.
$sql = mysql_query("SELECT * FROM wd009 where uniqueCode='$uniqueCode'");
Instead, do something like this:
$stmt = $mysqli->prepare("SELECT * FROM wd009 where uniqueCode=?");
$stmt->bind_param($uniqueCode);
$stmt->execute();
while ($stmt->fetch()) {
.....
You'll also want to do it this way for the update statement too.
If you have a lot of data in that table you may want to restrict the columns returned in the SQL statement so it lessens the load on the database.

php authentication script

I need the following authentication script finished. I am weak at php/pdo so I do not know how to ask for the number of rows equalling one and then setting the session id's from the results of the query. I need to not only set the $_SESSION['userid'] but also the ['company'] and the ['security_id'] as well from the results.
here is what I have:
$userid = $_POST['userid'];
$password = $_POST['pass'];
if ( $userid != "" || $password != "" )
{
$sql = "SELECT * FROM contractors WHERE userid = '" . $userid . "' AND password = '" . $password . "'";
$result = $dbh->query( $sql );
} else
{
echo "login failed. Your fingers are too big";
}
Optional Information:
Browser: Firefox
DO NOT EVER USE THAT CODE!
You have a very serious SQL injection open there. Every user input that you take, whether from cookies or CGI, or wherever, must be sanitized before it's used in an SQL statement. I could easily break into that system by attempting a login with an username like:
user'; UPDATE contractors SET password = '1337'
... after which I could then login as anyone. Sorry if I sound aggressive, but what that code does is like forgetting to lock the front door into your company which probably doesn't even contain an alarm system.
Note that it doesn't matter whether the input is actually coming from the user or not (perhaps it's in a pre-filled, hidden from). From the security point of view, anything that comes from anywhere outside has to be considered to contain malicious input by the user.
As far as I know, you need to use the quote function of PDO to properly sanitize the string. (In mysql, this would be done with mysql_real_escape_string().) I'm not an expert on PDO, mind you, somebody please correct if I'm wrong here.
Also you probably shouldn't store any passwords directly in the database, but rather use a hash function to create a masked password, then also create a hash from the user provided password, and match the hashes. You can use the PHP hash function to do this.
As for other issues, I don't know if the approach you have on SQL SELECT is the best approach. I would just select the corresponding user's password and try matching that in the program. I don't think there's any fault in the method you're using either, but it just doesn't seem as logical, and thus there's a greater chance of me missing some bug - which in case of passwords and logins would create a window for exploits.
To do it your way, you need to notice that the result you are getting from the PDO query is a PDOStatement, that doesn't seem to have a reliable function to diretly count the amount of result rows. What you need to use is fetchAll which returns an array of the rows, and count that. However, as I said this all feels to me like it's open for failures, so I'd feel safer checking the password in the code. There's just too much distance from the actual password matching compasion for my taste, in such a security-critical place.
So, to the get the resulting password for the userid, you can use PDOStatement's fetch() which returns the contents of the column from the result. Use for example PDO::FETCH_ASSOC to get them in an associative array based on the column names.
Here's how to fix it:
$userid_dirty = $_POST['userid'];
$password_dirty = $_POST['pass'];
$success = false; // This is to make it more clear what the result is at the end
if ($userid != "" || $password != "") {
$userid = $dbh->quote($userid_dirty);
$passwordhash = hash('sha256',$password_dirty);
$sql = "SELECT userid, passwordhash, company, security_id FROM contractors WHERE userid = ".$userid;
$result = $dbh->query( $sql );
if ($result) { // Check if result not empty, that userid exists
$result_array = $result->fetch(PDO::FETCH_ASSOC);
if ($result_array['PASSWORDHASH'] == $passwordhash) {
// login success
$success = true;
// do all the login stuff here...
// such as saving $result_array['USERID'], $result_array['COMPANY'], $result_array['SECURITY_ID'] etc.
} // else fail, wrong password
} // else fail, no such user
} else {
// fail, userid or password missing
echo ' please enter user id and password.';
}
if (!$success) {
echo ' login failed.';
}
Of course, the code can be cleaned up a bit, but that should explain what needs to be done. Note that since the password is both hashed, and never used in the SQL, it doesn't actually need cleaning. But I left it there just in case, since in the original code it was used in the query.
Note that all the code concerning storing passwords need to be changed to store the hash instead of the password. Also, it would be a very good idea to use a salt added to the password before hashing.
Also, I provided the code simply for educational purposes - I just thought that code was the clearest way to explain how to do this. So do not mistake this site as a service to request code. :)
The php manual is an excellent resource for learning PHP. It looks like you know a little SQL, and you have heard of PDO, which is a good start. If you search google for "PDO", or look in the PHP manual for the term, you'll find the PDO section of the manual. It looks like you've found the ->query function, so now you need to see what that returns. Going to the that function's manual page, we see that it returns a PDOStatement object. The word PDOStatement is helpfully linked to the relevant page in the manual, which lists the methods available on that object. There is a rowCount() method that will likely do what you want.

Categories