I'am newbie with PHP and i have a issue with my php form validation that return this error, if the username and the password are not defined.
Notice: Undefined variable: username in D:\hpsp\controller\loginvalidation.inc.php on line 64
I use 2 functions (usernameValidation & passwordValidation) to check if $_POST input are correct or not but i don't know what's and where i have to put the correct script, Thank you in advance.
<?php
session_start();
require_once('../model/pdo.inc.php');
// function for checking the username validation (not empty & Regex)
function usernameValidation($username) // Username as parameter
{
if ( !empty($_POST['username']) )
{
$username = strtolower(htmlspecialchars($_POST['username'])); // username will be tranform to lowercase before regex matching
if ( preg_match('#^[a-z0-9\.]{5,20}$#', $username) ) // 5 <= username lenght <= 20 in lowercase character to be valid
{
return true; // return true when the username is valid
}
else
{
echo "Invalid username, please re-try" ;
}
}
else
{
echo "Enter your username";
}
}
// function for checking the password validation (not empty & Regex)
function passwordValidation($password) // Password as parameter
{
if ( !empty($_POST['password']) )
{
$password = htmlspecialchars($_POST['password']) ; // Protect the password
if ( preg_match('#^[a-zA-Z0-9\.-_#$()]{6,10}$#', $password) ) // 6 <= password length <= 10 character to be valid
{
return true; // return true when password is valid
}
else
{
echo "Invalid password, please re-try";
}
}
else
{
echo "Enter your password";
}
}
if ( usernameValidation($username) == true AND passwordValidation($password) == true )
{
// PDO Query (SELECT ...)
}
I would do something like this (note you never want to echo out individual messages for email and password to stop hackers gaining information about which is correct:
session_start();
require_once('../model/pdo.inc.php');
//username and password will contain the posted resulte or FALSE
$username = usernameValidation();
$password = passwordValidation();
if (!$username OR !$password) {
echo 'Invalid username or password!';
die;
}
// PDO Query (SELECT ...)
// function for checking the username validation (not empty & Regex)
function usernameValidation() { // Username as parameter
if (!empty($_POST['username'])) {
$username = strtolower(htmlspecialchars($_POST['username'])); // username will be tranform to lowercase before regex matching
if (preg_match('#^[a-z0-9\.]{5,20}$#', $username)) { // 5 <= username lenght <= 20 in lowercase character to be valid
return $username; // return true when the username is valid
}
}
return FALSE;
}
// function for checking the password validation (not empty & Regex)
function passwordValidation() { // Password as parameter
if (!empty($_POST['password'])) {
$password = htmlspecialchars($_POST['password']); // Protect the password
if (preg_match('#^[a-zA-Z0-9\.-_#$()]{6,10}$#', $password)) { // 6 <= password length <= 10 character to be valid
return $password; // return true when password is valid
}
}
return FALSE;
}
Define your functions withow arguments
function usernameValidation(){ ... }
and call it
if ( usernameValidation() == true AND passwordValidation() == true )
<?php
session_start();
require_once('../model/pdo.inc.php');
// function for checking the username validation (not empty & Regex)
function usernameValidation($username) // Username as parameter
{
if ( !empty($_POST['username']) )
{
$username = strtolower(htmlspecialchars($_POST['username'])); // username will be tranform to lowercase before regex matching
if ( preg_match('#^[a-z0-9\.]{5,20}$#', $username) ) // 5 <= username lenght <= 20 in lowercase character to be valid
{
return true; // return true when the username is valid
}
else
{
echo "Invalid username, please re-try" ;
}
}
else
{
echo "Enter your username";
}
}
// function for checking the password validation (not empty & Regex)
function passwordValidation($password) // Password as parameter
{
if ( !empty($_POST['password']) )
{
$password = htmlspecialchars($_POST['password']) ; // Protect the password
if ( preg_match('#^[a-zA-Z0-9\.-_#$()]{6,10}$#', $password) ) // 6 <= password length <= 10 character to be valid
{
return true; // return true when password is valid
}
else
{
echo "Invalid password, please re-try";
}
}
else
{
echo "Enter your password";
}
}
$username = $_POST['username'];
$password = $_POST['password'];
if ( usernameValidation($username) == true AND passwordValidation($password) == true )
{
// PDO Query (SELECT ...)
}
Change your last if condition to the code below:
if ( usernameValidation($_POST['username']) == true AND passwordValidation($_POST['password']) == true )
{
}
In your functions only use the variables $username and $password and not(!) $_POST['username'] and $_POST['password']
you are defined $username and $password, it is $_POST['username'] and $_POST['password']. And you can also make function without parameter. by making these change your problem will solved.
Related
I am working on password validations. All other validations are working fine. I have to add initials validation on password. Password should not contain full name or username and first/last character of username and full name. I am trying to get it with strpos function but it's not working.This is my code i had tried with 2 ways but not working.
<?php
$name = "katlina john smith";
$uname = "testinguser";
$password = "john";
$password = "kjs#123"; // first initials of name
$password = "testing#ps"; //These password format should not be accepted
if (strpos($password,$name) !== false || strpos($password,$uname) !== false) {
echo 'Username found in the password';
}
//2nd way
if (preg_match("#(($uname)|($name))#", $password))
{
echo 'Username found in the password';
}
Here is the complete answer
$name = "katlina john smith";
$uname = "testinguser";
$password = "john";
if ( (strpos($name,$password) !== false ) || ( strpos($uname,$password ) !==
false ) ) {
echo 'password not valid';
}
Use this:
$name = "katlina john smith";
$username = "testinguser";
$password = "katlina#test123";
For PHP 7:
if (strpos(strtolower($password), strtolower($username)) === false || passContainsName($name, $password)) {
echo 'password not valid in PHP 7'.PHP_EOL;
}
function passContainsName($name, $password){
foreach (explode(" ", $name) as $toCheck) {
if (strpos(strtolower($password), strtolower($toCheck)) === false) {
return true;
}
}
return false;
}
For PHP 8:
if (str_contains(strtolower($password), strtolower($username)) || passContainsName($name,$password)) {
echo 'password not valid';
}
function passContainsName($name, $password){
foreach (explode(" ", $name) as $toCheck) {
if (str_contains(strtolower($password), strtolower($toCheck))) {
return true;
}
}
return false;
}
fiddle [here] with php 7 and 8 examples1
I cannot manage to add a password hash in my sign up code. I am new to PDO and I tried different things but cannot manage to make a working registration with password hash!
Can someone help me? Here my code:
<?php
include('header.php');
// Check if logged in
if($user->is_loggedin()!="")
{
$user->redirect('home.php');
}
$error='';
if(isset($_POST['btn-signup']))
{
// trim empty spaces on inserted data
$uname = trim($_POST['name']);
$umail = trim($_POST['email']);
$upass = trim($_POST['password']);
$repeat_password = trim($_POST['repeat_password']);
// validate username
if($uname=="") {
$error.= "provide username ! <br>";
}
// validate e-mail
else if($umail=="") {
$error.= "provide email id ! <br>";
}
else if(!filter_var($umail, FILTER_VALIDATE_EMAIL)) {
$error.= 'Please enter a valid email address ! <br>';
}
// validate password
else if($upass=="") {
$error.= "provide password ! <br>";
}
else if(strlen($upass) < 6){
$error.= "Password must be atleast 6 characters <br>";
}
else if( $upass!=$repeat_password){
$error.= "Password Does Not Match <br>";
}
else
{
// check if email is already taken
try
{
// prepare statement
$stmt = $DB_con->prepare("SELECT email FROM users WHERE email=:umail");
$stmt->execute(array(':umail'=>$umail));
$row=$stmt->fetch(PDO::FETCH_ASSOC);
if($row['email']==$umail) {
$error.= "sorry email id already taken ! <br>";
}
// if everything is validated save data
else
{
if($user->register($uname,$umail,$upass))
{
$_SESSION['success']='You have been Registered Successfully';
$user->redirect('login.php');
}
}
}
// set the error mode
catch(PDOException $e)
{
echo $e->getMessage();
}
}
}
And here the class "user"
<?php
class User
{
private $db;
function __construct($DB_con)
{
$this->db = $DB_con;
}
// get user by passed in data
public function register($uname,$umail,$upass)
{
try
{
// $new_password = password_hash($upass, PASSWORD_DEFAULT); // Creates a password hash;
$new_password = $upass;
// prepared statement
$stmt = $this->db->prepare("INSERT INTO users(name,email,password,user_type)
VALUES(:uname, :umail, :upass,'user')");
// bind param with values
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
$stmt->execute();
return $stmt;
}
// set the error mode
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function login($umail,$upass)
{
try
{
// prepare statement
$stmt = $this->db->prepare("SELECT * FROM users WHERE email=:umail LIMIT 1");
$stmt->execute(array(':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0)
{
if($upass==$userRow['password'])
{
$_SESSION['user_id'] = $userRow['id'];
$_SESSION['name'] = $userRow['name'];
$_SESSION['role'] = $userRow['user_type'];
return true;
}
else
{
return false;
}
}
}
// set the error mode
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function is_loggedin()
{
if(isset($_SESSION['user_id']))
{
return true;
}
}
public function redirect($url)
{
header("Location: $url");
}
public function logout()
{
session_destroy();
unset($_SESSION['user_id']);
return true;
}
}
?>
In the commented line in the class script you can see a try I made, it hashed the password but then the pw wouldn't be saved in my sql database.
Sorry if the question is stupid but I am learning :)
I want to point out few things first:
Do not use trim to users password. Unless if you want to restrict your users from entering spaces to their passwords.
Use === when doing comparison. It is better because it checks datatype at the same time. For example if you have "2" and 2 and you use == operator it equals. It is good practice to check datatype because it prevents alot error from happening.
As what comes to problem that you wanted to get answer
You don't use password_hash function at any point. You only assign raw password to variable and assign this variable to bind_param function.
$new_password = $upass;
Should be instead
$new_password = password_hash($upass, PASSWORD_DEFAULT);
However i do not recommend using PASSWORD_DEFAULT as you could get more secure hash by using PASSWORD_ARGON2I. You can check more information about password_hash from PHP manual.
And to help you out even more: when you want to verify that user enters correct password at login you need to use password_verify(). It compares hash to password that user entered and if it is correct this function will return true.
Example:
$login_status = password_verify($_POST['password'], $user_password_from_database);
if($login_status === true) {//set session etc...}
You can read more about password_verify here
There is definitely a logical flaw somewhere in this code, but I can't find it. The issue is that regardless of input, it echo's success (simulating a redirect to the main page). I don't know why. Here's the code:
$signIn = new UserService($dbuser, $dbpass, $dbhost, $dbname); //Create new class instance
$signIn->sec_session_start(); //Begin session
$_SESSION['token'] = $token; //Store token valualbe in super global variable
//***************************************************************************************//
//***************************************************************************************//
//Begin Login Functions
if(isset($_POST['username'], $_POST['password'],$_POST['siteToken'])) {
//Assign POST submissions to passable php variables
$username = $_POST['username'];
$password = $_POST['password'];
$passedToken = $_POST['siteToken'];
//Check Token Values (prevent CSRF attacks)
/*
if($passedToken != $_SESSION['token']) {
$error = "CSRF attack detected. Please close your browser and try again.";
$signIn->csrfAttackLog($username);
echo $error;
exit();
}
*/
//Test if both fields are not null
if($username == "" || $password = "")
{
$error = "Not all fields were entered<br />";
echo $error;
exit();
}
//Start login process
else
{
$success = $signIn->login($username, $password);
if ($success == true)
{ //Login Successful
echo "Success!"; //Direct to main page.
exit();
}
//Specific login failure determination
else
{
switch ($success){
case 1:
$error = "Your account has been locked.";
echo $error;
break;
case 2:
$error = "Invalid Username/Password (2)";
echo $error;
break;
case 3:
$error = "Invalid Username/Password";
echo $error;
break;
case 4:
$error = "Invalid Username/Password (3)";
echo $error;
break;
}
}
}
Here's the login class method:
public function login($username, $password)
{
//****************//
$this->username = $username;
$this->password = $password;
$user_Id = "";
$user = "";
$hashPassword = "";
$dbPassword = "";
$salt = "";
$userBrowser = "";
//**************// Local declerations
$this->connect(); //connect to database
if ($stmt = $this->dbh->prepare("SELECT UserId, Username, Pass, Salt FROM user WHERE Username = :param1 LIMIT 1")) //Prepared procedure
{
$stmt->bindParam(':param1', $this->username); //Bind $this->username to parameter
$stmt->execute(); //Execute the prepared query
if ($stmt->rowCount() == 1) //If the user exists
{
$this->user = $stmt->fetch(PDO::FETCH_ASSOC); //Grab the variables from the selected database row
$user_Id = $this->user['UserId']; //Transfer variables from array to local variables
$user = $this->user['Username'];
$dbPassword = $this->user['Pass'];
$salt = $this->user['Salt'];
if($user_Id = "")
echo "Why";
//Check if account has been locked
if($this->checkBrute($user_Id, $this->dbh) == true)
{
//Account is locked
return 1; //Used in userControl as a switch condition: Indicates a locked account
//Possibly send an email here
} else {
$hashPassword = hash('sha512', $this->password.$salt); //Hash the password with the unique salt
if($dbPassword == $hashPassword)
{ //Check if the password in the database matches the password the user submitted
//Password is correct!
$userBrowser = $_SERVER['HTTP_USER_AGENT']; // Get the user-agent string of the user
$_SESSION['p_id'] = $user_Id; //Store user id to global session variable
$_SESSION['userName'] = $user; //Store username to global session variable
$_SESSION['loginString'] = hash('sha512', $hashPassword.$userBrowser); //Hash the concentanation of the hashedpassword (password + salt) and userBrowser
//Login succesful!!!!!!
return true;
} else {
//Password is not correct
//Record this attempt in the database
$now = time();
$userIp = $_SERVER['REMOTE_ADDR'];
$insert = $this->dbh->query("INSERT INTO loginattempts (UserId, UserIp, EventTime) VALUES ('$user_Id', 'userIP', '$now')");
if($insert == false){
return 2; //Used in userControl as a switch condition: Indicated a failure to log failed login attempt
} else {
return 3; //Used in userControl as a switch condition: Indicates an inccorect password
}
}
}
}
else
{
//No user exists
return 4;
}
}
}
I know the SQL queries work: I've tested them outside this code. I don't understand why it keeps returning true. PHP hasn't thrown any exceptions or errors (and yes, I've read many times "don't write your own login functions. Use one that already works." This is not a public site. I'm just doing it for the heck of it). Any help is appreciated.
Your login code has various return codes - true if everything works, or numbers to indicate various error states. You're then checking the return value with:
if ($success == true)
PHP isn't strongly typed, so it will cast return values to a boolean for that comparison; and any non-0 integer will evaluate to true. To do a type check, as well as a value check, you need to use the strict comparison operator:
if ($success === true)
That will evaluate true if $success is both true and a boolean.
What is the wrong in my code. it's say... (1) Username required (2) Password is not correct if i click Log in button without username and password, but it' should be show All filed required.
<?php
if(isset($_POST['action']) && isset($_POST['action']) == "Sign in")
{
include("../secure/content/database/db.php");
$uname = mysql_real_escape_string(trim($_POST['uname']));
$pass = md5(mysql_real_escape_string(trim($_POST['pass'])));
/// check user name
$sql = mysql_query("SELECT uname FROM members WHERE uname = '$uname'");
$num_u = mysql_num_rows($sql);
// check user password
$sql2 = mysql_query("SELECT pass FROM members WHERE pass = '$pass'");
$num_p = mysql_num_rows($sql2);
$err = array();
if(isset($uname) && isset($pass))
{
if( empty($uname) && empty($pass))
{
$err[] = "All field required";
}
else
{
if(empty($uname))
{
$err[] = "Username required";
}
else
{
if($num_u == 0) $err[] = "Username is not correct";
}
if(empty($pass))
{
$err[] = "Password required";
}
else
{
if($num_p == 0)
$err[] = "Password is not correct";
}
}
if(!empty($err))
{
foreach($err as $er)
{
echo "<font color=red>$er</font><br>";
}
}
else
{
include("content/include/newsession.php");
$tm = date("Y-m-d H:i:s");
$ip = $_SERVER['REMOTE_ADDR'];
$rt = mysql_query("insert into plus_user_login(id,uname,ip,tm, status, tm_out) values ('$_SESSION[id]','$_SESSION[uname]','$ip','$tm', 'ON', '')");
echo mysql_error();
print "<script>";
print " self.location='content/index.php';";
print "</script>";
}
}
}
Any idea or Solution..
On this line:
$pass = md5(mysql_real_escape_string(trim($_POST['pass'])));
You are calling md5() which will always return a value, even if $_POST['pass'] was empty. So empty($pass) will never be true.
The md5() sum of an empty string or NULL does not result in an empty value, so you always have a value in $pass, even if $_POST['pass'] was empty.
// Never empty
$pass = md5(mysql_real_escape_string(trim($_POST['pass'])));
// Because:
var_dump(md5(""));
string(32) "d41d8cd98f00b204e9800998ecf8427e"
When you check for the presence of $uname & $pass, use the $_POST values instead:
// instead of
if( empty($uname) && empty($pass))
// do
if(empty($uname) && empty($_POST['pass']))
please remove this md5 from following line, md5 create a string if pass is empty.
md5(mysql_real_escape_string(trim($_POST['pass'])));
use this.
mysql_real_escape_string(trim($_POST['pass']));
use md5 in another.
Your are running into this problem because empty strings are hashable see this.
Change
if(isset($uname) && isset($pass))
to
if(isset($uname) && isset($_POST['pass']))
if(isset($_POST['login'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
if(empty($username) || empty($password)) {
$error = 1;
$error_message = 'Please fill in all the required fields.';
} else {
get_login_name($username, $password);
//The commented line works...
//$query = mysql_query("SELECT /* user_logged true, page login */username, password FROM members WHERE username = '".$username."' AND password = '".sha1($password)."' LIMIT 1");
}
if(mysql_num_rows(get_login_name($username, $password)) == 0) {
echo get_login_name($username, $password);
$error = 1;
$error_message = 'Incorrect username or password.';
} elseif ($error == 0) {
//Other stuff....
}
}
Function:
function get_login_name($password, $username) {
global $myDB;
global $config;
$query = "SELECT /* page == login, functions.php */username, password FROM members WHERE username = '".$username."' AND password = '".sha1($password)."' LIMIT 1";
$result = $myDB->Execute($query) or die(GetDbError($myDB->ErrorMsg()));
return $result;
}
How properly check if username or password incorrect ? (part if(mysql_num_rows(g.....)
In my opinion something wrong i have done ir function get_login_name with return and checking. By the way, using adodb.
EDIT:
After all i decided a bit test it, so, let's leave function as it now and let's check username and password part:
if (!is_null(get_login_name($password, $username))) {
echo get_login_name($password, $username);
$error = 1;
$error_message = 'Incorrect username or password.';
}
If username or password incorrect ir gives me:
username,password which mean result doesn't found at all (no user, if user correct gives same)
Ok, let's enter valid user and pass, and it gaves:
username,password zero,0a706ce75f3bc195c8ed7be5a21d3766abb0d384
What's wrong ?
Essentially, if get_login_name has a return, that means the query returned a match for username and password which means the combination is correct, otherwise, no result means there's no match so you could say either username or password is incorrect (because they don't exist or one of them is wrong). If $Result has a value using get_login_name would likely to be just:
if (!is_null(get_login_name($password, $username)))
// correct
else
// incorrect
Play around with it and see the results.
Ech, after testing managed it to work :)
That seems this part fails :/
if (!is_null(get_login_name($password, $username)))
So, hole code:
if (!$myDB->Affected_Rows()) {
//if(mysql_num_rows($query) == 0) {
$error = 1;
$error_message = 'Incorrect username or password.';
}
What i have ? Just changed it to:
if (!$myDB->Affected_Rows()) {
Thank you all guys who tryed help.