PHP Save new item to Switch Statement - php

I am currently working on a Banlist for my game, and it is currently functional, but I want to know if there is a way to use post ex: http://example.com/banlist?newentry=SAVETHIS
and save into a new case in the switch statement.
Basically, I want to store the "SAVETHIS" after the newentry into a brand new case.
Here's an image to help you understand what I mean.

You need some type of storage instead of writing a code that writes itself.
if(isset($_GET['newentry'])){
if(file_put_contents('./banlist.txt', $_GET['newentry'] . PHP_EOL, FILE_APPEND) === false){
die('no perms, cant create file in '.getcwd());
} else {
die('user banned');
}
} elseif(isset($_GET['id'])){
if(in_array($_GET['id'], explode(PHP_EOL, file_get_contents('./banlist.txt')))){
die('user is banned');
}
}
See this as an EXAMPLE code, preferred is to use a database and put this code behind a login wall of some sorts as it has NO SECURITY checks.
In its current state, if I know the location of this script I can simply create a loop and ban every user in range of 0 to MAX_INT. Also it does not check if the user is already banned, so I can fill up your hard drive by looping a simple script to infinity. Noor does it check for potential XXS attacks.

Related

Authentication without database ( PHP )

How to securely authenticate a user without using any type of database.
authenticate.php?username={$_GET['username']}&password={$_GET['password']}
if ($_GET['username'] == "secret_username" && password == "secret_password")
{
$_SESSION['user'] = $username;
header("Location: password_protected_page.php");
exit;
}
This method seems to be an option. Is it secure?
Use a file to hold your data.
have a users.txt below your public html like so:
username:hashedpassword
then you use fopen
<?php
$filename = "/home/users.txt";
$file = fopen( $filename, "r" );
$display = fread( $file, filesize( $filename ) );
fclose($file);
?>
Then explode it by newline and then |, then check if the first is equal to username and the second is equal to md5(password).
Seems like the easiest way to me...
I would at least post for authentication but otherwise it should work fine.
Definitely, you can do that. But, just use POST.
There is nothing wrong with the process. Even when we use database, we actually do the same thing but just using some select command.
You might be thinking about password hash, but they are used so that, even if the 3rd party gets a hold of database dump(somehow), they can never actually decrypt the password, as hash are one way function. Now in you case you are not using database, so that's not a problem.
However the problem lies in scalability. Are you sure that there will always be just one user of the system. If yes, then its okay, else go for DB.
I learned PHP on my own. I never took a course nor had a mentor. I had issues "getting" datasbase calls, as they seemed so convoluted compared to other PHP which seemed natural. I started using this a long time ago.
You can create a text file (username.php) in a directory OFF the web server accesible folders.
(consider permissions!)
So you have /root/users and in that folder you have (by username)
/root/users.Joe.php
/root/users/Juan.php
/root/users/Tim.php
Tim.php contents
<?php
$userpath='/var/www/html/users/Tim';
$password='Timspassword';
?>
Now when Tim logs on wee have code that does this:
<?php
include '/root/users/'.$_POST[username].'.php';
if ($password == $_POST['password'])
{
$_SESSION['loggedin']='yes';
$_SESSION['expire']='<how much time you need?>';
}
?>
This way you can more easily create new users . BTW I use an index.php in each users folder that will do very little if not logged in as that particular user that matches the name of the folder. You should also use https. You could also use password encryption/decryption in these user passwords.
Truth be told, Database injection is a real vulberability. Daily I get hackers looking for databases on my sites. THERE ARE NONE, so they go away.
no databese required.

Stop user using email verification link more than once. PDO prepared statement not functioning

EDIT: based on first reply I got below,I reworked my code and it now works... first checking the given email address to find the gamer id. Then checking the verfication state based on the gamer id. So if they change their email address in the future it will still know whether it's already been verified.
Below is my final code, (I've changed some name for items, so its not an exact copy/paste of my own code).
function email_not_verified ($email) { //check it's not already verified
include ('../connect.php'); // Include connect to database functions
$findUser= $db->prepare("SELECT game_id FROM players WHERE email=?");
$findUser->execute(array($email));
$user = $findUser->fetch();
if ( $findUser){
$veri= $db->prepare("SELECT sent_verification FROM players WHERE game_id=?");
$veri->execute(array($user["game_id"]));
$results = $veri->fetch();
$final = $results["sent_verification"];
}
if ($final == 1){
return TRUE;
}
else{
return FALSE;
}
}
Thanks again for the help.
Below, is my original question.
I'm trying to figure out a simple setup that stops a user repeatedly verifying their email address. As when they verify their email I'm awarding them a bonus of 300 credits for in store game purchases. I obviously don't want to keep dishing that out each time they follow their emailed verification link.
So I'm trying to run a check first, before the normal verification script is run.
But surprise, surprise: its not working...
I was trying to search my database for the email address with the verification field set to '1', I'd then see how many times it found this result. If it found it '0' times then that's fine to verify, if it found it once then its already been verified before.
function email_not_verified ($email) {
include ('../connect.php'); // connect to database
//check it's not already verified
$checkEmail= $db->prepare("SELECT * FROM players WHERE sent_verification=?, email=?");
$checkEmail->execute(array('1', $email));
$check2 = $checkEmail->rowCount();
if ($check2 = 1){
return TRUE;
}
else{
return FALSE;
}
}
I've been using
file_put_contents('results.txt',$check2);
to see the results of the code regardless of whether its putting out a TRUE or FALSE. But the result comes back as '0', even though I can see from looking at my database it should be '1'.
I'm not sure if there's a whole easier way to approach this, I keep trying to get my head around bind values but it's not yet sinking in... I'll continue to try.
Thanks for any help, guidance, pointing out the obvious... I feel like I've taken the wrong path with my script but can't think how else to approach it...
Cheers
Jon
Your if statement is wrong. You're using the assignment operator instead of comparison. This doesn't matter though because rowCount isn't always reliable, which is probably where the actual problem is. What you need to do is fetch the first row and see if you get a row back.
However, you probably don't want to attach this to e-mail verification. When users change their e-mail address, you will want to verify that new address and you probably don't want to give them 300 more credits each time they do. Otherwise, someone could programmatically change their e-mail address over and over again, creating a lot of credits for themselves.
I would separate out the 300 free credits as a coupon or something that can only be used once per account. On e-mail verification, if that coupon hasn't already been used up for that account, use it and mark it as such in your database. This could be done simply by adding another column for new_account_bonus_credits or something.

Stop if invalid user input

I want to check/filter user input. If, for example, the user chosen value does not match what we have on the db, I want the script/query to stop--obviously for security reasons.
Which is correct?
if (!floatval($esc_size || $esc_sizeid) )
{
echo "Invalid Size </br>";
$thread_id = mysqli_thread_id($con);
/* Kill connection */
mysqli_kill($link, $thread_id);
mysqli_close($link);
}
or just simply
exit;
or is there a better, more secure way?
Thanks,
Jen
exit() will stop the script completely. PHP runs server-side and you are in complete control of what code is executed. For that reason, security is not an issue here.
From a user interface perspective, it is much better to put any updates to the db etc. in an if statement that only runs if the user input was valid and if it was not, display a friendly message to the user about what he/she did wrong.

How to prevent user generated faults?

i am new to PHP so don't know how this would turn out. Lets say i have a add friend page. And in the database lets say i have a table called "friends" and the following rows: my_id and friend_id and id_request.
And now i have a php page that will look something like: addfriend.php?id=friendid
And then i use the id from that link to insert in to the database my id and that friendid.
The question is what will happen if someone enters "kdjfkldjlfk" in the link in the address bar?
you need to prevent those cases and validate
ex:
test that the $_GET['id'] isset and that the friendid is real , you could query the database to see that the id exists ...
If you mean "What will happen if someone visits the URI for an id that does not exist?", then it depends on what your PHP says should happen.
If your PHP doesn't check how many results it got from its SQL query, then it is quite possible that the page will spit out a 500 Internal Server Error.
If you've designed it properly, then it would return a document that explains that you cannot add a user that does not exist as a friend.
Actually, if you've designed it properly then the data should be sent via POST not GET since adding a friend is not an idempotent event. (See the HTTP specification — GET should be free of side effects)
You need to validate your user input. First, cast the $_GET value to an int type, and if it's equal to 0, tell them they've mistyped it.
$var = (int)$_GET['id'];
if($var == 0)
{
// Error
}
else
{
// The rest of your code
}
It turns out that PHP has some pretty cool filter functionality built-in. You should learn them and use them:
if (filter_var($_GET['id'], FILTER_VALIDATE_INT) === false) {
// error
}
if (filter_var($_GET['email'], FILTER_VALIDATE_EMAIL) === false) {
// error
}
if (filter_var($_GET['ip_address'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
// error
}
http://us.php.net/manual/en/function.filter-var.php

How to protect processing files

So I've a php form processing file; say a file name process.php with the codes as
<?php
$value = $_POST['string']; //Assume string is safe for database insertion
$result = mysql_query("INSERT into table values {$value}");
if($result) {
return true;
} else {
return false;
}
?>
Ideally, only someone who's logged in to my website shall be allowed to send that POST request to perform that insertion. But here, anyone who know this processing file's path and the request being sent can send any spoof POST request from any domain (if I'm not wrong). This will lead to insertion of unwanted data into the database.
One thing I did is, before the insertion, I checked whether a user is logged in or not. If not, I ignore the POST request. But how exactly should I secure my processing files from exploits?
As it stands this is vulnerable to SQL Injection. Make sure you use a parametrized query library like PDO for inserting the file and the mysql "blob" or "long blob" type. You should never use mysql_query().
You should also keep track of the user's id for user access control. It doesn't look like you have taken this into consideration.

Categories