Not displaying CSRF error when token is missing - php

I added anti-CSRF token today (storing in session & using bin2hex(random_bytes(32)), looks implemented good (sending in POST), but in case of missing token, it is not displaying any error for some reason, code:
<?php
// Initialize the session
session_start();
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['token'];
// Include config file
require_once "config.php";
// Define variables and initialize with empty values
$username = $password = "";
$username_err = $password_err = $login_err = "";
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
if (!empty($_POST['token'])) {
if (hash_equals($_SESSION['token'], $_POST['token'])) {
// Check if username is empty
if(empty(trim($_POST["username"]))){
$username_err = "Please enter username.";
} else{
$username = trim($_POST["username"]);
}
// Check if password is empty
if(empty(trim($_POST["password"]))){
$password_err = "Please enter your password.";
} else{
$password = trim($_POST["password"]);
}
// Validate credentials
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT id, username, password FROM users WHERE username = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_username);
// Set parameters
$param_username = $username;
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Store result
mysqli_stmt_store_result($stmt);
// Check if username exists, if yes then verify password
if(mysqli_stmt_num_rows($stmt) == 1){
// Bind result variables
mysqli_stmt_bind_result($stmt, $id, $username, $hashed_password);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: home.php");
} else{
// Password is not valid, display a generic error message
$login_err = "Invalid username or password.";
}
}
} else{
// Username doesn't exist, display a generic error message
$login_err = "Invalid username or password.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
} else{
echo "CSRF error";
}
// Close statement
mysqli_stmt_close($stmt);
}
}
}
// Close connection
mysqli_close($link);
}
?>
in case of missing token, response is blank, zero info
i am looking into that for like 2 hours and can not find the error, thanks in advance guys

Related

Login.php redirects to homepage instead of the header location

I am trying to make a notice board where only the admin can login and post updates(for a school) and I am very new to php. My code works fine in MAMP server on mac, but when I upload it to the 000webhost.com for testing purposes, it does not redirect to the correct page after login and redirects to the index.php page.
Here is my code. I did session_start in my conf.php file.
<?php
// Check if the user is already logged in, if yes then redirect him to welcome page
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
header('location: logout.php');
exit;
}
//check if not authorized
// Include config file
require_once '../conf.php';
// Define variables and initialize with empty values
$email = $password = '';
$email_err = $password_err = '';
// Processing form data when form is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Check if email is empty
if (empty(trim($_POST['email']))) {
$email_err = 'Please enter email.';
} else {
$email = trim($_POST['email']);
}
// Check if password is empty
if (empty(trim($_POST['password']))) {
$password_err = 'Please enter your password.';
} else {
$password = trim($_POST['password']);
}
// Validate credentials
if (empty($email_err) && empty($password_err)) {
// Prepare a select statement
$sql = 'SELECT id, email, password FROM users WHERE email = ?';
if ($stmt = mysqli_prepare($link, $sql)) {
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, 's', $param_email);
// Set parameters
$param_email = $email;
// Attempt to execute the prepared statement
if (mysqli_stmt_execute($stmt)) {
// Store result
mysqli_stmt_store_result($stmt);
// Check if email exists, if yes then verify password
if (mysqli_stmt_num_rows($stmt) == 1) {
// Bind result variables
mysqli_stmt_bind_result($stmt, $id, $email, $hashed_password);
if (mysqli_stmt_fetch($stmt)) {
//if ( password_verify( $password, $hashed_password ) ) {
if (($password == $hashed_password)) {
// Password is correct, so start a new session
//session_start();
// Store data in session variables
$_SESSION['loggedin'] = true;
$_SESSION['id'] = $id;
$_SESSION['email'] = $email;
// Redirect user to welcome page
header('Location: add_notice.php');
} else {
// Display an error message if password is not valid
$password_err = 'The password you entered was not valid.';
}
}
} else {
// Display an error message if email doesn't exist
$email_err = 'No account found with that email.';
}
} else {
echo 'Oops! Something went wrong. Please try again later.';
}
// Close statement
mysqli_stmt_close($stmt);
}
}
// Close connection
mysqli_close($link);
}
?>
Please help me with it. I would appreciate it a lot.
Just to close off the question...
If you are calling session_start() in the conf.php file then it needs to be included before any call for $_SESSION[] variables.
Right now you are checking for $_SESSION['loggedin'] before initialising the $_SESSION variables with session_start().
Move require_once '../conf.php'; above that if statement and it will work e.g.
<?php
// Include config file
require_once '../conf.php';
// Check if the user is already logged in, if yes then redirect him to welcome page
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
header('location: logout.php');
exit;
}
//check if not authorized
// Define variables and initialize with empty values
$email = $password = '';
$email_err = $password_err = '';
// Processing form data when form is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Check if email is empty
if (empty(trim($_POST['email']))) {
$email_err = 'Please enter email.';
} else {
$email = trim($_POST['email']);
}
// Check if password is empty
if (empty(trim($_POST['password']))) {
$password_err = 'Please enter your password.';
} else {
$password = trim($_POST['password']);
}
// Validate credentials
if (empty($email_err) && empty($password_err)) {
// Prepare a select statement
$sql = 'SELECT id, email, password FROM users WHERE email = ?';
if ($stmt = mysqli_prepare($link, $sql)) {
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, 's', $param_email);
// Set parameters
$param_email = $email;
// Attempt to execute the prepared statement
if (mysqli_stmt_execute($stmt)) {
// Store result
mysqli_stmt_store_result($stmt);
// Check if email exists, if yes then verify password
if (mysqli_stmt_num_rows($stmt) == 1) {
// Bind result variables
mysqli_stmt_bind_result($stmt, $id, $email, $hashed_password);
if (mysqli_stmt_fetch($stmt)) {
//if ( password_verify( $password, $hashed_password ) ) {
if (($password == $hashed_password)) {
// Password is correct, so start a new session
//session_start();
// Store data in session variables
$_SESSION['loggedin'] = true;
$_SESSION['id'] = $id;
$_SESSION['email'] = $email;
// Redirect user to welcome page
header('Location: add_notice.php');
} else {
// Display an error message if password is not valid
$password_err = 'The password you entered was not valid.';
}
}
} else {
// Display an error message if email doesn't exist
$email_err = 'No account found with that email.';
}
} else {
echo 'Oops! Something went wrong. Please try again later.';
}
// Close statement
mysqli_stmt_close($stmt);
}
}
// Close connection
mysqli_close($link);
}
?>

display full name after login using sessions

I have this login system using php, mysqli and sessions and it works fine but would be good if I can get the users full name displayed on the welcome page after login
I amended my code to the following on the login.php page and the welcome page code is after the login code but is not showing the full name
<?php
// Initialize the session
session_start();
// Check if the user is already logged in, if yes then redirect him to welcome page
if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){
header("location: user-account.php?user=$username");
exit;
}
// Include config file
require_once "registerconfig.php";
// Define variables and initialize with empty values
$username = $password = "";
$username_err = $password_err = "";
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Check if username is empty
if(empty(trim($_POST["user_name"]))){
$username_err = "Please enter username.";
} else{
$username = trim($_POST["user_name"]);
}
// Check if password is empty
if(empty(trim($_POST["user_pass"]))){
$password_err = "Please enter your password.";
} else{
$password = trim($_POST["user_pass"]);
}
// Validate credentials
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT user_id, user_name, user_pass, customer_name
FROM users WHERE user_name = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_username);
// Set parameters
$param_username = $username;
$param_customername = $customername;
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Store result
mysqli_stmt_store_result($stmt);
// Check if username exists, if yes then verify password
if(mysqli_stmt_num_rows($stmt) == 1){
// Bind result variables
mysqli_stmt_bind_result($stmt, $id, $username,
$hashed_password, $customername);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["user_id"] = $id;
$_SESSION["user_name"] = $username;
$_SESSION["customer_name"] = $customername;
// Redirect user to welcome page
header("location: user-account.php?user_name=$username");
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was not valid.";
}
}
} else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
// Close statement
mysqli_stmt_close($stmt);
}
// Close connection
mysqli_close($link);
}
?>
Welcome page code below
<?php echo htmlspecialchars($_SESSION["customer_name"]); ?>
Variable $customername is not defined and no value assigned to it. Because of that on line $_SESSION["customer_name"] = $customername; empty value assigned to $_SESSION["customer_name"].

Users Account Redirection

I am creating a code that the user will redirect depends on their user type
I've tried if,else statement but there's some errors
"mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables"
<?php
// Initialize the session
session_start();
// Include config file
require_once "config.php";
// Check if the user is already logged in, if yes then redirect him to
welcome page
if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){
if($_SESSION["userType"] == "administrator"){
header("location: index.php");
exit;
}else($_SESSION["userType"] == "user"){
header("location: userpage.php");
exit;
}
}
// Define variables and initialize with empty values
$username = $password = $userType = "";
$username_err = $password_err = "";
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Check if username is empty
if(empty(trim($_POST["username"]))){
$username_err = "Please enter username.";
} else{
$username = trim($_POST["username"]);
}
// Check if password is empty
if(empty(trim($_POST["password"]))){
$password_err = "Please enter your password.";
} else{
$password = trim($_POST["password"]);
}
// Validate credentials
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT * FROM users WHERE username = ? and userType = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "ss", $param_username);
// Set parameters
$param_username = $username;
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Store result
mysqli_stmt_store_result($stmt);
// Check if username exists, if yes then verify password
if(mysqli_stmt_num_rows($stmt) == 1){
// Bind result variables
mysqli_stmt_bind_result($stmt, $id, $username,
$hashed_password, $userType);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
$_SESSION["userType"] = $userType;
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was incorrect.";
}
}
}else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// Close connection
mysqli_close($link);
}
?>
I'd like to see how to redirect the users depending on their user types.
You missed one argument on mysqli_stmt_bind_param()
So your code should be:
mysqli_stmt_bind_result($stmt, 'ss', $param_username, $user_type);
See https://www.php.net/manual/en/mysqli-stmt.bind-param.php

When submitting a form I receive my error but not sure why

Why do I seem to receive my echo statement "error" when submitting this form?
I got this code from https://www.tutorialrepublic.com/php-tutorial/php-mysql-login-system.php for register.php.
It was working fine for my users up till yesterday and can't seem to find why?
I thought maybe it was my config.php but it does print the error message if a username is already in use so it doesn't seem to be config.php. I messaged the website that I got the code from and they couldn't help me.
<?php
// Include config file
require_once "config.php";
// Define variables and initialize with empty values
$username = $password = $confirm_password = "";
$username_err = $password_err = $confirm_password_err = "";
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Validate username
if(empty(trim($_POST["username"]))){
$username_err = "Please enter a username.";
} else{
// Prepare a select statement
$sql = "SELECT id FROM sign_in_account WHERE username = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_username);
// Set parameters
$param_username = trim($_POST["username"]);
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
/* store result */
mysqli_stmt_store_result($stmt);
if(mysqli_stmt_num_rows($stmt) == 1){
$username_err = "This username is already taken.";
} else{
$username = trim($_POST["username"]);
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// Validate password
if(empty(trim($_POST["password"]))){
$password_err = "Please enter a password.";
} elseif(strlen(trim($_POST["password"])) < 6){
$password_err = "Password must have atleast 6 characters.";
} else{
$password = trim($_POST["password"]);
}
// Validate confirm password
if(empty(trim($_POST["confirm_password"]))){
$confirm_password_err = "Please confirm password.";
} else{
$confirm_password = trim($_POST["confirm_password"]);
if(empty($password_err) && ($password != $confirm_password)){
$confirm_password_err = "Password did not match.";
}
}
// Check input errors before inserting in database
if(empty($username_err) && empty($password_err) && empty($confirm_password_err)){
// Prepare an insert statement
$sql = "INSERT INTO sign_in_account (username, password) VALUES (?, ?)";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "ss", $param_username, $param_password);
// Set parameters
$param_username = $username;
$param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Redirect to login page
header("location: login.php");
} else{
echo "Something went wrong. Please try again later. error: 1";//Error 1 = form submission
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// Close connection
mysqli_close($link);
}
?>
The output should go to my login.php page on successful result submission but prints my echo statement "echo "Something went wrong. Please try again later. error: 1";"

MySQLi Login Form with PHP - Fatal error: Uncaught Error: Call to a member function close() on boolean [duplicate]

This question already has answers here:
Fatal error: Call to a member function close() on a non-object. MySQLi issue
(3 answers)
Closed 1 year ago.
This is my code, and i think the issue is with $stmt->close(); as the error says. But i don't know how to fix it. I have searched the other questions but i can't find an answer (at least it's not helping me, the answers are all confusing :) )
Can you guys please help me?
<?php
// Initialize the session
session_start();
// Check if the user is already logged in, if yes then redirect him to
welcome page
if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){
header("location: dash.php");
exit;
}
// Include config file
require_once "config.php";
// Define variables and initialize with empty values
$username = $password = "";
$username_err = $password_err = "";
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Check if username is empty
if(empty(trim($_POST["username"]))){
$username_err = "Please enter username.";
} else{
$username = trim($_POST["username"]);
}
// Check if password is empty
if(empty(trim($_POST["password"]))){
$password_err = "Please enter your password.";
} else{
$password = trim($_POST["password"]);
}
// Validate credentials
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT id, username, password FROM employees WHERE username =
?";
if($stmt = $mysqli->prepare($sql)){
// Bind variables to the prepared statement as parameters
$stmt->bind_param("s", $param_username);
// Set parameters
$param_username = $username;
// Attempt to execute the prepared statement
if($stmt->execute()){
// Store result
$stmt->store_result();
// Check if username exists, if yes then verify password
if($stmt->num_rows == 1){
// Bind result variables
$stmt->bind_result($id, $username, $hashed_password);
if($stmt->fetch()){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: dash.php");
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was not
valid.";
}
}
} else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
// Close statement
$stmt->close();
}
// Close connection
$mysqli->close();
}
?>
This is what i'm getting - img
$stmt->close() needs to be inside if($stmt = $mysqli->prepare($sql)). If that fails, $stmt is set to false so you're trying to call file->close(), which makes no sense. You should also have an else block to display the reason why it failed.
// Validate credentials
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT id, username, password FROM employees WHERE username =
?";
if($stmt = $mysqli->prepare($sql)){
// Bind variables to the prepared statement as parameters
$stmt->bind_param("s", $param_username);
// Set parameters
$param_username = $username;
// Attempt to execute the prepared statement
if($stmt->execute()){
// Store result
$stmt->store_result();
// Check if username exists, if yes then verify password
if($stmt->num_rows == 1){
// Bind result variables
$stmt->bind_result($id, $username, $hashed_password);
if($stmt->fetch()){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: dash.php");
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was not
valid.";
}
}
} else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
// Close statement
$stmt->close();
} else {
die($mysqli->error);
}
}
Assuming the brackets are aligned...
If it's that line, $stmt = $mysqli->prepare($sql) resulted in $stmt being false. The close method doesn't exist for a boolean. Your code expected a statement object.
So preparing the statement went wrong.
Check the statement for syntax errors or invalid column and table names, etc.
The following lines should be switched together also:
// Bind variables to the prepared statement as parameters
$stmt->bind_param("s" $param_username); // Set parameters
$param_username = $username;

Categories