"Cant process the request", dealing with basic parameterized queries - php

I am trying something I found online (Extremely new to this) and none of it works. It's some random science project I decided to learn more about yet I am stuck on part 2 of the "procedures". https://www.sciencebuddies.org/science-fair-projects/project-ideas/Cyber_p008/cybersecurity/sql-injection#procedure
I watched videos but they only consist of just a user_ID and not a username and password. NOTE: Only the code dealing with login.php is causing problems.
<?php
include("global.php");
include("db.php");
session_start();
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// username and password are sent in the form
$username = $_POST['username'];
$password = $_POST['password'];
// Check if the username and password exist in the database
$sql = "SELECT username FROM users WHERE username = '$username' AND password = '$password'";
$stmt = msqli_stmt_init($db);
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo "SQL Statement Failed";
} else {
mysqli_stmt_bind_param($stmt, "ss", $username, $password );
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
$count = mysqli_num_rows($result);}
// If username and password matched then there is one row in the result
if ($count != 0) {
$_SESSION['login_user'] = strtolower($username);
header("location: search.php");
}
else {
$error = "Your Username or Password is invalid";
}
}
?>
It should have prevented a basic " 'or''=' " injection attack but it decided not to work entirely.

If you use query parameters — which is definitely a good idea — you must leave placeholders in your query. Use ? as the placeholder.
Like this:
$sql = "SELECT username FROM users WHERE username = ? AND password = ?";
You later bind variables to those parameters. You must bind the same number of variables as the number of parameter placeholders.
You got the error you described because you tried to bind variables to a query that had no parameter placeholders.

Related

My DB password and user filled-in password, do not match [duplicate]

This question already has answers here:
How to use PHP's password_hash to hash and verify passwords
(5 answers)
Closed 2 years ago.
I've a problem with my php login file. I ask the password from my db by checking the email. When I obtain this password I check it with the password the user filled in.
In the password_verify($Passwd, $row['Passwd']) the result will always return 0 but the result should be return 1 (password matches).
Why do my passwords not match with each other?
Login code:
<?php
if(isset($_POST['submit'])){
include_once '../includes/connection.php';
$Email = $_POST['email'];
$Passwd = $_POST['passwd'];
//Create Template
$sql = "SELECT Passwd FROM user WHERE Email = ?";
//Create Prepared Statement
$stmt = mysqli_stmt_init($conn);
//Prepare Prepared Statement
if(!mysqli_stmt_prepare($stmt, $sql)){
echo "SQL Statement Failed";
} else {
mysqli_stmt_bind_param($stmt, "s", $Email);
mysqli_stmt_execute($stmt);
$res = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($res)){
echo $Passwd . "<br>";
echo $row['Passwd'];
if(password_verify($Passwd, $row['Passwd'])){
echo "1";
} else {
echo "0";
}
}
}
} else {
header("Location: ../index.php?login=error");
}
?>
Registration code:
<?php
if(isset($_POST['submit'])){
include_once '../includes/connection.php';
$Username = $_POST['username'];
$Email = $_POST['email'];
$Passwd = $_POST['pwd'];
//Create Template
$sql = "INSERT INTO user (Username, Email, Passwd)
VALUES (?, ?, ?);";
//Create Prepared Statement
$stmt = mysqli_stmt_init($conn);
//Prepare Prepared Statement
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo "SQL Statement Failed";
} else {
$hashed_passwd = password_hash($Passwd, PASSWORD_DEFAULT);
//Replace '?' by the acctual data
mysqli_stmt_bind_param($stmt, "sss", $Username, $Email, $hashed_passwd);
//Run parameters inside database
mysqli_stmt_execute($stmt);
}
header("Location: ../index.php?signup=succes");
} else {
header("Location: ./index.php?sinup=error");
}
?>
Passwd is a varchar(50) column in the database.
The password_hash manual says:
it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice)
So you need to specify a minimum size of 60 characters for the password column in your database - but a larger size e.g. 255 is recommended in case the default hashing algorithm changes in future.
You'll also need to re-generate any existing passwords stored in the 50-character field, because they will have been truncated when they were saved, and the extra information has been lost, meaning those old passwords can never be verified.

Login page keeps showing error PHP and MySQL

I am having issues getting some simple (or it seems simple) coding to cooperate. I've tried stripping it completely and typing everything out. Here is the code:
<?php
session_start();
if(isset($_POST['login'])) {
$username = trim($_POST['username']);
$password = md5(trim($_POST['password']));
include('includes/admin.php');
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($con, $sql);
if(mysqli_num_rows($result) == 0) {
echo '<p>Incorrect login.<br>Return to Login Page</p>';
} else {
$_SESSION['user'] = $username;
echo '<p>Login successful.<br>Go to Admin Page</p>';
}
}
?>
The goal is to have it redirect to the login page if unsuccessful and to redirect to another admin page if successful. I keep getting the "Incorrect Login" error, even when I type in the correct username and password.
Side Note: I know to redirect, I need to use header('Location: link.php'), it is not included for testing purposes.
If you didn't save your password as MD5 hash in your database you will never match it, cause in the line above you hash the password via MD5 before using in the query.
MD5 isn't secure! Use the PHP internal functions (password_hash(), password_verify()) to create and check passwords!
Use prepared statements!
Example code:
<?php
// Save a new user password in DB
$username = 'Max User';
$password = 'My_Secr3t_Pa5sw0rd';
$passwordHash = password_hash($password, PASSWORD_BCRYPT);
$stmt = $mysqli->prepare("INSERT INTO `users` (`username`, `password`) VALUES(?, ?)");
$stmt->bind_param("ss", $username, $passwordHash);
$stmt->execute();
// Check user password
$stmt = $mysqli->prepare("SELECT `password` FROM `users` WHERE `username`=?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if (password_verify($password, $row['password']) {
echo "Password correct";
} else {
echo "Password incorrect!";
}
?>

My PHP login script is giving the following error

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' password='$2y$10$QV6'' at line 1
I'm fairly new to server-side scripting, please take a look at the syntax below and align it where neccesary or assist me with an alternative solution regarding this error.
<?php
$tbl_name = "user_accounts"; // Table name
// Connect to server and select database.
$mysqli = new mysqli("localhost", "root", "", "ems");
// email and password sent from form
$email = $_POST['email'];
$password = $_POST['password'];
if (!$_POST['email'] | !$_POST['password']) {
print "<script>alert('Your email & password do not match!');
javascript:history.go(-1);</script>";
exit;
}
// To protect MySQL injection
$email = stripslashes($email);
$password = stripslashes($password);
$email = mysqli_real_escape_string($mysqli, $email);
$password = mysqli_real_escape_string($mysqli, $password);
$hash = password_hash($password, PASSWORD_BCRYPT);
$sql = "SELECT account_type, email and password FROM $tbl_name WHERE email='$email', password='$hash'";
$mysqli_result = mysqli_query($mysqli, $sql) or die(mysqli_error($mysqli));
// Mysql_num_row is counting table row
$count = mysqli_num_rows($mysqli_result);
// If result matched $email and $password, table row must be 1 row
if ($count == 1) {
// Register $email, $password and redirect to file "index.php"
$_session['email'] = $email;
$_session['password'] = $password;
//Checking User Account Type
if ($_SESSION['account_type'] == 'user') {
header("location:user.php");
} else if ($_SESSION['account_type'] == 'admin') {
header("location:admin.php");
} else {
print "<script>alert('This Account Doesn't Exist!');
javascript:history.go(-1);</script>";
exit;
}
} else {
echo "Wrong email or Password";
}
?>
A few problems here:
You do not separate conditions using a comma, instead you use AND
You cannot check a password hash like that as it will be different every time as the salt is generated dynamically. Instead you should get the password from the row and use the password compare function password_verify().
You should use a prepared statement instead of escaping your input to avoid sql injection.
password_hash generates every time a new hash, even with the same value.
Your Query should only query for the email and then execute password_verify($password, $passwordFromQuery).
More about password_hash() here and about password_verify() here
I woud recommend using prepared statements. Read more about it here
Try this
$sql="SELECT account_type, email and password FROM $tbl_name WHERE email='".$email."', password='".$hash."'";
$mysqli_result=mysqli_query($mysqli, $sql) or die(mysqli_error($mysqli));

How to fetch username and matched id as Session?

I am trying to fetch different stats from whatever user is logged in. Then echo these stats out. currently when logging in i am setting a session with the username. Then i am trying to fetch the id from this username and check it again the table with the same ID and then fetch the rows from that table.
My guess is that since i am starting a session with only the username on login the code to fetch data wont work since the session does not provide the id row. i am unsure of how to get it to do that or if i am even right about that.
I appreciate all help, i am really stuck here.
This is my login code:
$query = "SELECT password FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
//USERDATA
$dbPassword = $row['password'];
if (password_verify($password, $dbPassword))
{
// echo "The details are correct.";
$_SESSION['loggedin'] = $username;
require_once('../../frontend/templates/account-actions.php');
}
else
{
echo "Passwords do not match!";
}
This is my code to fetch the stats data from the id of the username logged in:
$id = $_SESSION['loggedin'];
$query = "SELECT * FROM stats WHERE id='$id'";
$stmt = mysqli_query($conn, $query);
$result = mysqli_fetch_all($stmt,MYSQLI_ASSOC);
I have converted your code to mysqli Prepared Statement with Procedural approach.
$username = "username_to_search";
$password = "password"; //Password is in plain text since password hash has been used.
$stmt = mysqli_prepare($conn, "SELECT * FROM users WHERE username = ?");
/* bind parameters for markers */
mysqli_stmt_bind_param($stmt, "s", $username); //"s" defines the type of data in the following variables, i.e. String for $username.
/* execute query */
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$total_rows = mysqli_stmt_num_rows($stmt);
mysqli_stmt_bind_result($stmt, $id_fetched, $username_fetched, $password_fetched); //store every field fetched from the table in sequence. Note that I have added _fetched to make it easier to identify later.
if ($total_rows > 0) {
while(mysqli_stmt_fetch($stmt)) {
if (password_verify($password, $password_fetched)) {
$_SESSION['user_id'] = $id_fetched;
$_SESSION['username'] = $username_fetched;
require_once('../../frontend/templates/account-actions.php');
}
else {
echo "Invalid Password!";
}
}
} else {
echo "Invalid Username!";
}
Once you have stored the SESSION variables properly, now you can easily find everything related to this. User your $_SESSION["user_id"] to search.

login with username or email address in php

I am trying to create a login with username or email
My code is:
$username=$_REQUEST['login'];
$email=$_REQUEST['login'];
$password=$_REQUEST['password'];
if($username && $password) {
$query="select * from user_db where username='$username' and password='$password'";
} else if ($email && $password) {
$query="select * from user_db where email='$email' and password='$password'";
}
Login with username is success but login with email is not working. Please help me!
The login parameter is the same for both email and username. Not exactly incorrect if you have a single login box that accepts either.
You could put the condition in the query itself if you're not sure if it's an email or username.
$login=$_REQUEST['login'];
$query = "select * from user_db where ( username='$login' OR email = '$login') and password='$password'"
Edit:
A PDO-like solution is much more preferred nowadays as the above is subject to SQL injection. The logic stays the same, but you'd have it look something like this:
$query = "
SET #username = :username
SELECT * FROM user_db
WHERE ( username = #username OR email = #username)
AND password = :password
";
$statement = $pdoObject->prepare($query);
$statement->bindValue(":username", $login, PDO::PARAM_STR);
$statement->bindValue(":password", $password, PDO::PARAM_STR);
$statement->execute();
You are setting the same value to two variables, and then using an if/else. Both if statements are equivalent.
You need to figure out if $_REQUEST[login] contains a valid email address, and if so use the email field of the database. Otherwise, use the username field.
Also, you should not be putting variables directly into the query. Use prepared statements.
Well i know this is an old post but i've found that some people are still going to view it so i wanted to put a easy way to allow both email and username on the same input
my code is as follows
if
(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/", $name_of_same_input) )
{
$un_check = mysql_query("SELECT uname FROM eusers WHERE uname = '' ") or die(mysql_error());
echo "loging in with username"; //code
}
elseif
(preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/", $name_of_same_input) )
{
$un_check = mysql_query("SELECT umail FROM eusers WHERE umail = '' ") or die(mysql_error());
echo "loging in with email"; //code
}
<?php
require "connectdb.php";
$email =$_POST["email"];
$mobile = $_POST["mobile"];
$password =$_POST["password"];
//Test variables
//$email = "admin#xyz.com";
//$mobile = "9876543210";
//$password ="#!b7885a$";
$sql_query = "SELECT email FROM RegisterUser WHERE `email` LIKE '$email' OR `mobile` LIKE '$mobile' AND `password` LIKE '$password';";
$result = mysqli_query($con,$sql_query);
if(mysqli_num_rows($result) > 0 )
{
$row = mysqli_fetch_assoc($result);
$email = $row["email"];
echo "Login Successful...Welcome ".$email;
}
else
{
echo "Login Failed...Incorrect Email or Password...!";
}
?>
Hi, for me works something like this:
if ( !isset($_POST['emailuser'], $_POST['userPass']) ) {
// Could not get the data that should have been sent.
die ('Please fill both the username and password field!');
}
$emailuser = ($_POST['emailuser']);
$emailuser = trim($emailuser);
if ($stmt = $con->prepare('SELECT userEmail or userName, userPass FROM users WHERE userEmail = ? or userName = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
$stmt->bind_param('ss', $emailuser, $emailuser);
$stmt->execute();
// Store the result so we can check if the account exists in the database.
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->bind_result($userName, $userPass);
$stmt->fetch();
// Account exists, now we verify the password.
// Note: remember to use password_hash in your registration file to store the hashed passwords.
if (password_verify($_POST['userPass'], $userPass)) {
// Verification success! User has loggedin!
// Create sessions so we know the user is logged in, they basically act like cookies but remember the data on the server.
session_regenerate_id();
$_SESSION['loggedin'] = true;
$_SESSION['name'] = $emailuser;
$_SESSION['emailuser'] = $userName;
header('location: /menu.php');
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
$stmt->close(); } ?>
$username=$_REQUEST['login'];
$email=$_REQUEST['login'];
This is wrong, you are using $_REQUEST['login'] for both email and username. Why don't you just use email?
If $_REQUEST['login'] doesn't have email address, of course this wont return you anything.
Also, both of your if statements will always execute, unless the fields are empty. right?
Take the login out, enforce the users to login with email addresses. also, take md5 of the password. who stores raw passwords these days?
$username=$_REQUEST['username'];//I'm assuming your code here was wrong
$email=$_REQUEST['email'];//and that you have three different fields in your form
$password=$_REQUEST['password'];
if (validate_username($username)) {
$query="select * from user_db where username='".$username".' and password='".validate_password($password)."'";
} else if (validate_email($email)) {
$query="select * from user_db where email='".$email."' and password='".validate_password($password)."'";
}
//... elsewhere...
function validate_username(&$username) {
if (strlen($username) <= 1) { return false; }
//return false for other situations
//Does the username have invalid characters?
//Is the username a sql injection attack?
//otherwise...
return true;
}
function validate_email(&$email) {
//same deal as with username
}
function validate_password(&$password) {
//same deal as with username
}
Note, if you have only two fields (login and password), then the distinction between email and username is meaningless. Further note that you should really be using PHP PDO to construct and execute your queries, to prevent security breaches and make your life waaay easier.
if (validate_username($username)) {
$query="select * from user_db where username='".$username".' and password='".validate_password($password)."'";
} else if (validate_email($email)) {
$query="select * from user_db where email='".$email."' and password='".validate_password($password)."'";
}

Categories