String comparison regardless of case - php

I'm trying to find different variations of "Username" or "Password" , as shown below, in an case-insensitive manner:
$unVar1 = "username";
$unVar2 = "user name";
$usernameVariations1 = strcasecmp($unVar1, $unVar2);
$unVar3 = "User";
$unVar4 = "id";
$usernameVariations2 = strcasecmp($unVar3, $unVar4);
$pwVar1 = "password";
$pwVar2 = "pass";
$passwordVariations1 = strcasecmp($pwVar1, $pwVar2);
if ($element->value === $usernameVariations1
|| $element->value === $usernameVariations2
|| $element->value === $passwordVariations1) {
echo "Weee!";
}
else {
echo "boo!";
}
The problem is it outputs "boo" for each element in the foreach() output. What am I doing wrong? Is it possible to put all of these values in an array? Thanks.

You're making this more complicated then it needs to be. If your usernames and passwords not case sensitive, just make them lowercase when you compare them:
if (strtolower($username) === strtolower($element->value))
{
// ok
}
Now if you're allowing spaces to be added to the middle, and abbreviations, then you can try plan B:
$valid_usernames = array('Username', 'username', 'user name', 'UsE Nam');
if (in_array($element->value, $valid_usernames))
{
// ok
}
Keep in mind that you are now responsible for keeping $valid_usernames complete.

Related

how to secure $_GET

I'm trying to secure my $_GET inputs everything are working the problem is $_GET['action'] can't pass preg_match() and always resulta in:
"action is not valid"
I don't know why it's happening, the action can have only two values like or hate which both are in lowercase but still can't pass it.
if(isset($_GET['username']) && isset($_GET['action']))
{
$username = $_GET['username'];
$action = $_GET['action'];
$user_filter_a = mysqli_real_escape_string($username);
$user_filter_b = mysqli_real_escape_string($user_filter_a);
$user_filter_c = strip_tags($user_filter_b);
$action_filter_a = mysqli_real_escape_string($action);
$action_filter_b = mysqli_real_escape_string($action_filter_a);
$action_filter_c = strip_tags($action_filter_b);
$action_filter_c_lower = strip_tags($action_filter_b);
if(preg_match('%^[a-z0-9\.]{4,69}$%',$user_filter_c))
{
if(preg_match('%^[a-z]$%',$action_filter_c_lower))
{
if($action_filter_c_lower=='like')
{
echo 'you have liked this post';
}elseif(action_filter_c_lower=='hate')
{
echo 'you have hated this post';
}
}else
{
echo 'action is not valid';
}
}else
{
echo 'username is not valid';
}
When you need to validate that a string is completely comprised of letters, you can use ctype_alpha().
Code: (Demo)
$string = 'asdgadsfg';
if (ctype_alpha($string)) {
echo "all alphabetical";
} else {
echo "not entirely alphabetical";
}
Output:
all alphabetical
If you need to check if a submitted value is like, hate, or [something else]; create a "whitelist" array to look up the value.
Code: (Demo)
$string = 'like';
$whitelist = ['like', 'hate'];
if (in_array($string, $whitelist)) {
echo "valid: $string";
} else {
echo "invalid: $string";
}
Output:
valid: like
Additional tips:
if(isset($_GET['username']) && isset($_GET['action']))
can be written more simply as:
if (isset($_GET['username'], $_GET['action'])) {
You shouldn't be performing escaping until just before applying the data to the query, this way you don't accidentally mangle your data or confuse yourself. Honest, I always use prepared statements to build a query with user-submitted data, so I'll recommend that you research that topic.
In your regular expression, you don't need to escape a dot inside of a character class so the character class can look like this: [a-z0-9.] If you also wish to allow capital letters, you can add i after the end pattern delimiter (%) so that it looks like %^[a-z0-9.]{4,69}$%i or %^[a-z\d.]{4,69}$%i.
_lower is a strange thing to append to your variable name, because you aren't calling any functions that force the string to lowercase.
The total number of actions is limited. It is more secure to not use the user input at all. Instead, use a switch statement with a default action:
$userAction = strtolower($_GET['action']);
switch($userAction) {
case "like":
$action = "like";
break;
case "hate":
$action = "hate";
break;
default:
$action = "default-action";
}
Or, you can have the list of valid actions in an array:
$validAction = ["like","hate","other"];
$action = "";
if (in_array($_GET["action"],$validAction)){
$action = $_GET["action"];
}
Here you have the guarantee that the action is valid.

how to compare array for single result using if statement

i was doing validation for user form after each validation i used to store "valid" in a array index and at last comparing them like this:
if(isset($fullname)){
if ($valid["name"]=="valid"&&$valid["username"]=="valid"&&$valid["password"]=="valid"&&$valid["email"]=="valid") {
session_start();
$_SESSION["reg_name"] = $fullname1;
$_SESSION["reg_username"] = $username1;
$_SESSION["reg_email"] = $email1;
$_SESSION["reg_password"] = $password1;
$_SESSION["reg_gender"] = $_REQUEST['gender'];
header("location:validation&insertion.php");
}
Well i will check validation and then make session .
My question is there any short way to check the whole array across a single value like "valid"?
I hope you have understand my question.Comment it if it is not asked well.
Do not rate as negative.Please ignore my grammar mistakes.I hate those who edit my question's grammar.
You can just count the number of unique values and check if it's equal to 1, then check one value if it is "valid".
if (count(array_unique($valid)) === 1 && $valid["name"] === "valid") {
session_start();
$_SESSION["reg_name"] = $fullname1;
$_SESSION["reg_username"] = $username1;
$_SESSION["reg_email"] = $email1;
$_SESSION["reg_password"] = $password1;
$_SESSION["reg_gender"] = $_REQUEST['gender'];
header("location:validation&insertion.php");
}
Or just simply check if a "notvalid" value is found in the array:
if (!in_array("notvalid", $valid)) {
session_start();
$_SESSION["reg_name"] = $fullname1;
$_SESSION["reg_username"] = $username1;
$_SESSION["reg_email"] = $email1;
$_SESSION["reg_password"] = $password1;
$_SESSION["reg_gender"] = $_REQUEST['gender'];
header("location:validation&insertion.php");
}

How to read a file line by line in php and compare it with an existing string?

I tried to write this program to compare a user-name in a file with an entered user-name to check whether it exists, but the program doesn't seem to work. Please help. The program was supposed to open a file called allusernames to compare the usernames. If the user name was not found, add it to the file.
<?php
$valid=1;
$username = $_POST["username"];
$listofusernames = fopen("allusernames.txt", "r") or die("Unable to open");
while(!feof($listofusernames)) {
$cmp = fgets($listofusernames);
$val = strcmp($cmp , $username);
if($val == 0) {
echo ("Choose another user name, the user name you have entered has already been chosen!");
$valid=0;
fclose($listofusernames);
break;
} else {
continue;
}
}
if($valid != 0) {
$finalusers = fopen("allusernames.txt", "a+");
fwrite($finalusers, $username.PHP_EOL);
fclose($finalusers);
?>
you need to replace linefeed/newline character from each line to compare.
while(!feof($listofusernames)) {
$cmp = fgets($listofusernames);
$cmp = str_replace(array("\r", "\n"), '',$cmp);
$val = strcmp($cmp , $username);
if($val == 0) {
echo ("Choose another user name, the user name you have entered has already been chosen!");
$valid=0;
fclose($listofusernames);
break;
} else {
continue;
}
}
i have added following line in you code
$cmp = str_replace(array("\r", "\n"), '',$cmp);
I havent tested this but I wonder if you could use something like
<?php
$user = $_POST["username"];
$contents = file_get_contents("allusernames.txt");
$usernames = explode("\n",$contents);
if(in_array($user,$usernames))
{
echo "Choose another username";
}
else
{
$contents .= "\n".$user;
file_put_contents("allusernames.txt",$contents);
}
I think things like file get contents etc. need a certain version of PHP but they do make things a lot nicer to work with.
This also assumes that your usernames are seperated by new lines.
Yo can do this more simple with this code:
<?php
$username = $_POST["username"];
$listofusernames = 'allusernames.txt';
$content = file($listofusernames);
if(in_array($username, $content)) {
echo ("Choose another user name, the user name you have entered has already been chosen!");
} else {
$content[] = $username . PHP_EOL;
file_put_contents($listofusernames, implode('', $content));
}
?>

Validate password policy with PHP preg_match

I'm trying to validate a password using preg_match and RegEx but it doesn't seem to work. What I want to do is: ensure the password meets the following minimal conditions:
- Contains mixed case letters
- Contains atleast one number
- The rest can be anything as long as the two conditions above are met.
I've tried the following RegEx but it doesn't seem to work properly:
(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])
I've had other previous easier RegEx'es like: [A-Za-z0-9] but without success. I'm checking if preg_match($string, $pattern) == 0 (meaning the pattern doesn't match => validation fails) but it always returns 0. What am I doing wrong ?
Just add a starting anchor to your regex,
^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])
OR
^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9]).*
Example:
$yourstring = 'Ab';
$regex = '~^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])~m';
if (preg_match($regex, $yourstring)) {
echo 'Yes! It matches!';
}
else {
echo 'No, it fails';
} // No, it fails
I always try to avoid regex if it's possible so I took a different approach to the problem. The below code will test the password for at least one uppercase, one lowercase and one digit.
function isValidPassword($password)
{
$hasUppercase = false;
$hasLowercase = false;
$hasDigit = false;
foreach (str_split($password) as $char)
{
$charAsciiValue = ord($char);
if ($charAsciiValue >= ord('A') && $charAsciiValue <= ord('Z')) {
$hasUppercase = true;
}
if ($charAsciiValue >= ord('a') && $charAsciiValue <= ord('z')) {
$hasLowercase = true;
}
if ($charAsciiValue >= ord('0') && $charAsciiValue <= ord('9')) {
$hasDigit = true;
}
}
return $hasUppercase && $hasLowercase && $hasDigit;
}
var_dump(isValidPassword('Ab9c'));
var_dump(isValidPassword('abc'));
Output
bool(true)
bool(false)
I offer a different solution, mainly because regexp provides little error reporting, and you would have to manually test the string afterwards anywhay for cohesion. Consider breaking the patterns apart and adding their own error. Iterate each of the requirements, and test the pattern. Push errors into an array and check after for their existence. Return a predeclared variable as true/false for the purpose of validating using if(validate_password($pass)):. Here's the mockup:
function validate_password($pass){
$requirements = array();
//uppercase
$requirements['uppercase']['pattern'] = '/[A-Z]/';
$requirements['uppercase']['error'] = 'Your password must contain at least one uppercase letter.';
//lowercase
$requirements['lowercase']['pattern'] = '/[a-z]/';
$requirements['lowercase']['error'] = 'Your password must contain at least one lowercase letter.';
//requires a number
$requirements['number']['pattern'] = '/[0-9]/';
$requirements['number']['error'] = 'Your password must contain at least one number.';
//special characters
$requirements['special_character']['pattern'] = '/[!##$%^&*()\\-_=+{};\:,<\.>]/';
$requirements['special_character']['error'] = 'Your password must contain at least one special character.';
//length
$requirements['length']['pattern'] = '/^.{8,}/';
$requirements['length']['error'] = 'Your password must be at least 8 characters in length total.';
$is_valid = false; //our flag to return as true once all tests have passed.
$errors = false;
//validate all requirements
foreach($requirements as $idx => $req):
if(preg_match($req['pattern'], $pass, $matches)):
$is_valid = true;
else:
$errors[] = $req['error'];
$is_valid = false;
endif;
endforeach;
//if we had errors above
if($errors):
$is_valid = false;
foreach($errors as $error):
echo '<p>', $error, '</p>';
endforeach;
endif;
return $is_valid;
}
$pass = 'j!Adz6'; //change this to test
echo validate_password($pass);
And an eval.in example for your pleasure.

PHP Read txt file and check if username password exists

I have a bunch of passwords and usernames stored in a txt file and i need to check for matches. I know this is not a safe method but its for leaning purposes.
This code writes the usernames and passwords to a txt file
if(isset($_POST['register'])) //
{
$user = $_POST['username'];
$password=$_POST['password'].PHP_EOL;
$fh = fopen("file.txt","a+");
fwrite($fh,$user." ".$password); //write to txtfile
fclose($fh);
}
Here's the code im having trouble with.
Username and Passwords are stored like this in results
username1 passwords1 username2 password2 etc.
So I need to check if result[0] = userinput AND if it exists check if result[1] = passwordInput and so on.
if(isset($_POST['Logg']))
{
//$_SESSION['username']=$user;
//$_SESSION['password']=$password;
$file = file_get_contents("file.txt"); // Returns a string
$result = explode(" ",$file);
$boolC= false;
for($i=0; $i< count($result); $i++)
{
if($result[$i] === $user)
{
$boolC=true;
$i =$i+1;
if($boolC === true)
{
if($result[$i]===$password)
{
echo 'Password and Username Correct';
}
}
}
}
}
Consider the possibility of having a space in the password so as any symbols. Perhaps you should split on a line break ("\n").
if( $result[$i] === $user && $result[$i+1] === $password )
The first part of the statement has to be true for the second one to be evaluated.
The $i variable is never changed
$file = "username1 passwords1 username2 password2";
$result = explode(" ",$file);
$user = "username1";
$password = "passwords1";
for($i=0; $i< count($result); $i++){
if($result[$i] === $user && $result[$i+1] === $password)
{
echo 'Password and Username Correct';
}
}
Before you go ahead and try to correct this code, I strongly suggest you stay away from storing passwords in a plain text file. It is a huge security hole in your system.
Another architecture issue I can see is that your code would fail if the username or passwords contain a space in them. You probably should use line jumps as a delimiter instead (\n).
I think there is nothing wrong with the logic of the original post.
You should print all the variables to check whether they hold the correct value or not.
the "$user" and "$password" variables are global or not since they would not be known within the braces of the other if block i.e in the block where you check $_POST['logg']

Categories