bindParam & bindValue don't work? - php

I'm trying to make a register/login system. To check if usernames and email addresses aren't used, I use this :
$username = $_POST['uLogin'];
$usernameLC = strtolower($username);
$query1 = $db0->query("SELECT userLogin FROM tbuser WHERE userLogin=':login';");
$query1->bindValue(":login", $usernameLC, PDO::PARAM_STR);
But it doesn't work. I can create as much users with the same username as I want. By extension, it also won't let me connect onto the website as it doesn't bind values or anything, so it can't compare my username to the one in the DB.
Verifying if a username is not taken worked when I used it like this
$username = $_POST['uLogin'];
$usernameLC = strtolower($username);
$query1 = $db0->query("SELECT userLogin FROM tbuser WHERE userLogin='$usernameLC';");
But it isn't the proper way to go :/
Can anybody help ? :)

They're not working because your binded values contain quotes; remove them.
userLogin=':login'
as
userLogin=:login
"Verifying if a username is not taken worked when I used it like this"
WHERE userLogin='$usernameLC'
You need to remove the quotes in the bind as already stated on top, and make sure you're using PDO to connect with, as stated below; if that is the case.
Using setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) would have signaled the syntax errors.
Read up on how to use prepared statements in PDO, to prepare and execute:
http://php.net/pdo.prepared-statements
An insight:
Make sure you are indeed using a PDO connection rather than a mysqli-based (it's unknown). I see these types of questions often, where OP's use mysqli_ to connect with and querying with PDO.
Those different MySQL APIs do not intermix with each other.
Connecting through PDO on PHP.net
If you're using mysqli_ to connect with:
See mysqli prepared statements and how to use them.
Add error reporting to the top of your file(s) which will help find errors, if any in regards to your POST arrays, or other possible errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Error reporting should only be done in staging, and never production.
Edit:
"Thanks, it works great. When logging in though, comparing submitted password to the password in DB returns false. I try stocking the received password in $_SESSION['test'] to see what it gets and print_r($_SESSION); returns me this : Array ( [test] => Array ( [userPwd] => test12 [0] => test12 ) ) (test12 is my password, userPwd is the password Field in the db) Any idea ? ^^"
In regards to a comment you left about using passwords.
It seems you are storing passwords in plain text, rather than a hash. This is highly discouraged, as well as being stored in sessions; a very bad idea.
Read up on sessions hijacking.
See this Q&A on Stack on hashed passwords:
Q: Php 5.5 And Pdo Login
A: https://stackoverflow.com/a/27023211/
Using PHP's password_hash() function and password_verify() function.
For PHP < 5.5 use the password_hash() compatibility pack.
A note about the column type and length when storing a hashed password.
The password column should be VARCHAR.
It should also be long enough to store the hash.
Using VARCHAR(255) is best.

First off, if you're going to prepare, use ->prepare(), and remove quotes in your named placeholders, they don't need to have that:
$query1 = $db0->prepare("SELECT userLogin FROM tbuser WHERE userLogin= :login");
Then $query1->execute(), the prepared statement after the binding, so all in all:
$username = $_POST['uLogin'];
$usernameLC = strtolower($username);
$query1 = $db0->prepare('SELECT userLogin FROM tbuser WHERE userLogin = :login'); // prepare
$query1->bindValue(':login', $usernameLC, PDO::PARAM_STR); // bind
$query1->execute(); // execute

Related

Struggling to get PHP variable to work in MySQL Select request

I'm attempting to get my code to pull up a username based on the password a user inputs. It works successfully when I bake the actual password into the code, but I haven't found any way to get the variable in successfully.
The troublesome line is:
$result=$dbh->prepare('SELECT * from account WHERE password = (' & $formpassword & ')');
The variable is $formpassword.
I have variables successfully working on an INSERT statement elsewhere in my code, using this system:
$_query = "INSERT INTO account (username, password) ";
$_query = $_query."VALUES ('".$formusername."', '".$formpassword."')";
^^^ I have tried using the above system for my SELECT statement, but it doesn't appear to work either.
Sorry if my post is unclear or anything, I'm not remotely experienced with programming...
Thanks for the help!
Never store plain text passwords! Please use PHP's built-in functions to handle password security. If you're using a PHP version less than 5.5 you can use the password_hash() compatibility pack. It is not necessary to escape passwords or use any other cleansing mechanism on them before hashing. Doing so changes the password and causes unnecessary additional coding.
When using prepared statements you put placeholders in the sql.
$stmt=$dbh->prepare('SELECT * from account WHERE password = :formPassword');
$stmt->execute([':formPassword'=>$formpassword]);
$row = $stmt->fetch();
$stmt = $pdo->prepare('INSERT INTO account (username, password) VALUES (:username, :formPassword)');
$stmt->execute([':username'=>$formusername,':formPassword'=>$formpassword]);
You should be able to use " (Double quotes) instead of ' (Single quotes). Then you can just use the variable without concatenation.
$result=$dbh->prepare("SELECT * from account WHERE( password = $formpassword )");

Using BCRYPT wrong with mysqli

I am attempting to create a register page and am having trouble trying to hash my password using PASSWORD_BCRYPT with mysqli. Can someone explain what is wrong with my code below?
<?php
if(isset($_POST['Register'])) { // checking that form is submitted
session_start(); //creating variables for form entries
$FName = $_POST['First_Name'];
$LName = $_POST['Last_Name'];
$Email = $_POST['Email'];
$PW = $_POST['Password'];
$StorePassword = password_hash($PW, PASSWORD_BCRYPT, array('cost' => 10));
$sql = $con->query("INSERT INTO users (Fname, Lname, Email, Password)Values('{$FName}', '{$LName}', '{$Email}', '{$PW}')");
header('Location: Login.php');
Firstly, you're using the wrong variable for the password in the query being $PW rather than the intended $StorePassword variable where you're using it on top, then passing it to the hashing function.
Your password is being stored as "rasmuslerdorf" rather than "$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a"
Example pulled from the manual.
If that still doesn't work then that function may not be available for you to use and will need to use the password compatibility pack
(if PHP < 5.5) https://github.com/ircmaxell/password_compat/
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.
Consult these following links
http://php.net/manual/en/mysqli.error.php
http://php.net/manual/en/function.error-reporting.php
and apply that to your code.
You may have errors in your query but you're not checking for them.
Plus, seeing you did not post your HTML form, make sure it is using a POST method and that all inputs bear the proper name attributes.
Just for argument's sake; your posted code is missing a closing brace }
Also add exit; after header, should there be more code after that. Otherwise, your code may want to continue to execute.
Make sure you are indeed successfully connected using the same MySQL API as you are using for querying, being mysqli_. That is unknownst to us.
Different APIs such as mysql_ and PDO do not intermix with mysqli_ and vice-versa.
Make sure you're not outputting before header using session_start(); in the place it's in now; it looks as if there's a space before your opening PHP tag, that is considered as output. Error reporting will tell you that also.
Your present code is open to SQL injection. Use prepared statements, or PDO with prepared statements, they're much safer.
Footnotes:
Make sure that the password column is long enough to store the hash. PHP.net recommends using VARCHAR(255) and in order to accomodate for the future. Same thing for all columns and of the correct lengths/types.
http://php.net/manual/en/function.password-hash.php
"Note that this constant is designed to change over time as new and stronger algorithms are added to PHP. For that reason, the length of the result from using this identifier can change over time. Therefore, it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice)."

PHPMyAdmin database fills fields with 0 instead strings

I'm trying to create a sign up page for a website using PHP and PHPMyAdmin.
I have set 2 fields in the form needed for registration: email and password, with password confirmation.
Both of them are treated as string in PHP and as varchar in database. I don't know why, but everytime the user insert email and password and confirm, the new user is being inserted in database, but with email and password as 0 insted their real value. I'm sure that email and password values inside the PHP variables are correct, because i printed to output their content immediatly before the mysqli query, so i'm assuming that is a database problem.
I'm currently using Wamp Server for Windows 8 and PHPMyAdmin 4.1.14. Database is of type InnoDB and with latin_swedish_ci characters.
The query used in PHP is:
"INSERT INTO users (email,password) VALUES (email = '$email', password = '$password')"
using mysqli_query for the execution.
Instead of doing column equals variable, do:
VALUES ('$email','$password')
if an INSERT is indeed what you wish to use.
that syntax VALUES (email = '$email', password = '$password') is for when you want to check if a column equals something, when using a WHERE clause for example.
WHERE email = '$email'
or
WHERE email = '$email' AND password = '$password'
when doing an UPDATE as another example:
UPDATE table_name SET email = '$email', password = '$password'
WHERE column_x='something'
or, when doing a SELECT as another example:
SELECT * FROM table_name
WHERE column_x = 'something' OR column_y = 'something else'
Sidenote: OR can be replaced by AND, depending on the desired query.
Yet, when you do fix it, that present method is open to SQL injection. Use prepared statements, or PDO with prepared statements, they're much safer.
Look into those, you will be glad you did.
A basic example to prevent SQL injection is:
$email = mysqli_real_escape_string($con, $_POST['email']);
$password = mysqli_real_escape_string($con, $_POST['password']);
Error checking sidenote:
Add error reporting to the top of your file(s) which will help during production testing.
error_reporting(E_ALL);
ini_set('display_errors', 1);
and or die(mysqli_error($con)) to mysqli_query() while replacing $con with your DB connection variable.
Matteo - also, you should consider parameterizing your php syntax to prevent SQL injections. Better to do it now than to have to come back to it later. You can find an explanation of the concepts here; https://stackoverflow.com/questions/25316766/understanding-parameterized-queries-and-their-usage-in-preventing-sql-injections
INSERT INTO users (email,password) VALUES ('$email', '$password')
you don't need column name after VALUES. You have already specified it after table name.
By the way, you may want to look at php prepared statement

php crypt password and postgresql database

I'm new in PHP. I'm doing authentication, where I'm checking password with password stored in database PostgreSQL. On db site i used this function to crypt my password:
update ucty set psswd = crypt('some_pswd',gen_salt('md5')) where uid='1';
In my PHP srcipt I'm using this code:
$query = "SELECT meno, priezvisko, nickname, psswd, uid
FROM ucty
where nickname='$nickname' and psswd=crypt('$password', psswd)";
Everything works fine, but I'm not sure , that this is correct way to secure my password.
Any advice?
You're correct; this isn't the correct way to secure your password.
You're encrypting the password as part of the query. This can be logged (in plaintext), so it's very possible for intruders (or anyone listening to your traffic) to see users' passwords in plaintext.
"How can I prevent this?" Do your hashing on the server-side, within your PHP code. You can read up on this in the PHP manual.
Essentially, you want to have your query to set a password be something like this:
UPDATE ucty SET psswd=$hashed WHERE uid=1;
You're putting variables directly into the SQL statement. You didn't mention what method you're using to query the database, but you'll want to use prepared statements. This is a safe way to slide in user-supplied data (which $nickname and $password are).
This would be an example of a good way to use prepared statements:
$query = "SELECT meno, priezvisko, nickname, psswd, uid"
. " FROM ucty"
. " WHERE nickname=? and psswd=?";
$stmt = $dbh->prepare($query);
$stmt->execute(array($nickname, $hashedPassword));

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