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 )");
Related
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
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
I have tried to simply print/echo the data from this row in my table:
I then use the following code (without all the connect stuff):
//please just ignore the query part
$sql2 = "SELECT Password FROM bruger WHERE Brugernavn='$Login_Navn'";
$result2 = mysqli_query($con, $sql2);
$row_result2 = mysqli_fetch_assoc($result2);
print_r($row_result2);
And the output of this ends out being:
I would like to know what i have to do to make it appear without all the "Array ([Password]....." stuff, so it just ends out being plain "TestPassword".
-Do i have to use another function?
Thanks in advance!
Sidenote: Im creating a login system for a school project. It ain´t advanced in any way, and the security/encryption etc. is as low as it gets. But that´s not really what im interested in with the project.
If you have some reading material on how to create a login system properly tho´ it would be appreciated.
That would be echo $row_result2['Password'];
You need to specify the corresponding index of the array to get the respective element to be printed.
You would echo the place in the array
echo($row_result2['Password']);
If your query brings back multipule fields you could loop over them:
foreach($row_result2 as $key => $val)
{
echo($key . ':' . $value);
}
Lastly, instead of storing into a associated array, you could use mysqli's bind to bind the results to single varibles:
$sql2 = 'SELECT Password FROM bruger WHERE Brugernavn=?';
$stmnt = mysqli_prepare($con, $sql2);
mysqli_stmnt_bind_param($stmnt,'s',$Lpgin_Navn);
mysqli_stmnt_bind_result($stmnt,$result2);
mysqli_stmnt_execute($stmnt);
mysqli_stmnt_fetch($stmnt);
echo($result2);
Or object oriented:
$sql2 = 'SELECT Password FROM bruger WHERE Brugernavn=?';
$stmnt = $con->prepare($sql2);
$stmnt->bind_param('s',$Lpgin_Navn);
$stmnt->bind_result($result2);
$stmnt->execute();
$stmnt->fetch();
echo($result2);
The use of mysqli_prepare protects your database from SQL injection attacks (consier if $Login_Navn = "'; drop table burger; --"). Binding the parameter tells it which string to sanitize when running the query. It also will speed up the time it takes to run the same query multiple times on different passed strings.
Lastly, never store passwords if you can help it. If you must, you should read the best practices for storing passwords. This, currently, includes salting (with random salt) and hashing (using a hash algo that is not currently known to be broken) the password before storing it in the 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));
I am about to launch my website and security is important so i wanted to outline what I have done to secure the site. Please correct me if I am wrong and if I need something else:
To connect to our server, I have a two-factor authenitcation enabled via VPN.
The site uses SSL
Data is encrypted at rest.
I have a log monitoring tool
WHen users enter data into the database i use mysql_real_escape_string(); and when i display user data i use htmlspecialchars();
Passwords are stored using md5 encryption.
Sample insert query:
// I use these on every page
$username = removeBadChars($_SESSION["username"]);
$password = removeBadChars($_SESSION["password"]);
//Sanitized data
$_SESSION["username"] = $username;
$_SESSION["password"] = $password;
//Query to display
$sql = "select `User_name`, `User_id`, `User_kind` from `clientele`
where `username` = '$username' AND `password`='$password'";
$query = mysql_query($sql) or die ("Error: ".mysql_error());
while ($row = mysql_fetch_array($query)){
$name = htmlspecialchars($row['User_name']);
$uid = htmlspecialchars($row['User_id']);
$uis = htmlspecialchars($row['User_kind']);
}
mysql_free_result($query);
//Insert Query
$title = mysql_real_escape_string($_POST['title']);
$comment = mysql_real_escape_string($_POST['comment']);
$insert = "INSERT INTO table (Title, Comment)
VALUES ('".$title."', '".$comment."')";
$query = mysql_query($insert) or die ("Error: ".mysql_error());
Use a stronger hash function (e.g. sha256)
Append a salt (random value for every user) to the password before hashing it
Use prepared statements (MySQLi) instead, to avoid the possibility of forgetting to escape data before entering it into the database
Do not store user information in $_SESSION. Instead, store a session variable that means nothing to the outside world, changes every time someone logs in, and links to the user account. - This only applies to cookies. drinks some caffeine
Be careful putting data from user in attribute values (e.g. <span title="FULLNAME">), as additional escaping is needed (quotes, spaces if not using quotes, etc)
Note: This list is not exhaustive. It only lists things I noticed that were wrong with the short snippets you provided.
For safety you should probably use a PDO or mysqli_ functions and skip that old-school mysql_ junk, it's no longer being developed. Here's how to use the PDO:
$pdo = new PDO('mysql:host=localhost;dbname=whatever', $username, $password);
$statement = $pdo->prepare('select `User_name`, `User_id`, `User_kind` from `users`
where `username` = :user AND `password`= AES_ENCRYPT(:pass,:user)');
$statement->bindParam(':user', $_GET['user']);
$statement->bindParam(':pass', $_GET['pass']);
$results = $statement->execute();
var_dump($results->fetchAll());
the parameters are much safer because when you bindParam it automagically validates. Others have mentioned using md5 hashing, but there are plenty of databases for "decoding" them and also rainbow table attacks, so they're not very secure. Here I'm using mysql's AES_ENCRYPT for the password, and using the username as the key for demonstration purposes, you'd probably want to generate your own key and store it somewhere, because you can AES_DECRYPT with that... There are libraries for better encryption you should check out, like scrypt.
Whatever you do, do not use addslashes() it's insecure
On top of that you should look into securing your server's OS and Apache in other ways, like making not advertise version numbers and running apache as it's own users etc. Check out the Open Web Security Project website for tons of security info.