How to prevent the user from abusing a button? - php

i'm quite a beginner with PHP and i tried to make something to get xp when cliking the button. You just need to click and it gives xp, then it refresh the page to refresh the player's stat on screen.
<form method="post">
<p><input type="submit" value="Kill the mob" name="add20xp" /></p>
</form>
<?php
if (isset($_POST['add20xp']))
{
$add20xp =("UPDATE users SET exp = (exp + 20)");
$execadd20xp = mysqli_query($connection, $add20xp);
echo '<meta http-equiv="refresh" content="0.1" />';
}
?>
The problem is that i want to prevent the user from smashing the button to prevent bugs and things like that... I tried to put sleep(1) but i can just keep spamming, wait the seconds and it works so it's not very useful.
Thanks for the help !

Save the last time the update was done in session state. Then, only allow the button to be pressed after (last time + 2 seconds) (Two seconds was chosen since that was the suggested interval in your original question).
if (isset($_POST['add20xp'])) {
if (!isset($_SESSION['last_post'])) {
$_SESSION['last_post'] = 0;
}
$currtime = time();
if ($currtime > ($_SESSION['last_post'] + 2)) {
$_SESSION['last_post'] = $currtime;
// ... process the post.
$add20xp =("UPDATE users SET exp = (exp + 20)"); // fix this line
$execadd20xp = mysqli_query($connection, $add20xp);
echo '<meta http-equiv="refresh" content="0.1" />';
}
}
As #Martin noted above in his comment, you want to do the update only for the user who pressed the button, which is the meaning of the comment "fix this line."

If you want to disable the button for 3 seconds after the form is submitted you can use this:
if(sessionStogare.getItem('submitted') === true){
document.querySelector('input[type="submit"]').disabled = true;
setTimeout(function(){
document.querySelector('input[type="submit"]').disabled = false;
sessionStorage.removeItem("submitted");
}, 3000);
}
document.querySelector("body").onclick = function() {
sessionStorage.setItem("submitted", true);
};
We will note the submission in the sessionStorage and check, if the form has been submitted every time we load the page. Then, we will disable the button and enable it after 3 seconds.

Change your php page to this:
// the beginning of the page:
<?php
// start a SESSION
session_start();
// setup a $_SESSION variable
if (!isset($_SESSION["timestamp"]))
$_SESSION["timestamp"] = 0;
//
// now put the $_POST part
if (isset($_POST['add20xp'])) {
// check the time
$now = time();
if ($now - $_SESSION["timestamp"] > 2) {
// more than 2 seconds have passed since last $_POST
// update the time
$_SESSION["timestamp"] = time();
//
$add20xp =("UPDATE users SET exp = (exp + 20)");
$execadd20xp = mysqli_query($connection, $add20xp);
//
echo '<meta http-equiv="refresh" content="0.1" />';
exit;
} else {
// nothing, just let the page load like it is.
}
}
?>
Notice some important changes:
the use of $_SESSION vars -> these vars are stored and can be
retrieved at every page load -> you can use them to store the last
time an action took place
the $_POST part should be at the beginning
of the page -> otherwise after you send a form, you load the page ->
check the post -> then reload... it's not efficient
if you put the $_POST part at the beginning, you actually don't need the page reload with the meta tag -> because the data are already
updated

Related

Prevent user from entering page again after logout

I've created this code so that the user will not redirect onto the next page again. I set the maximum value on votenow button to 1 and once the user click the button again the value on the votenow button will not be added anymore since its maximum is 1. Everything works fine except that the user can still access the nextpage though the maximum value on the button was reached. Here's the code.
<?php
$errors = array();
$db = mysqli_connect("localhost","root","","registration");
if(isset($_POST['votenow']))
{
$votenow ="0";
$votenow1="1";
if($votenow != $votenow1){
$votenow = "update users set votenow = votenow + 1 WHERE votenow=0 LIMIT 1 ";
$run_vote = mysqli_query($db,$votenow);
echo '<script type="text/javascript">alert("hello!");</script>';
header ("Refresh:2; url=renewsys3.php");
}
else{
echo '<script type="text/javascript">alert("oh not again!");</script>';
header ("Refresh:2; url=renewsys2re.php");
}
}
?>
Can you guys help me or is there any other way so that the user will not enter the next page again? Btw, this is a voting system
The best way to use session:
$_SESSION['votenow'] = 0;
if (isset($_SESSION['votenow'])) {
if (!$_SESSION['votenow']) {
//do something
} else { // means $_SESSION['votenow'] == 1
// do something else
}
}
Redirect the URL to a different page (maybe homepage or any page) If the maximum vote is reached.
Let that code run before any other code so that the page won't load of the condition is true. It'll redirect immediately.

Incrementing the value of the post by every repeated form submission

I have a form sender which is posting a value of 6 to another form receiver. What I'm trying to achieve is store the posted value from sender into a variable in the receiverthen increment the variable it every time the sender posts. Then print the updated variable
This is what I have tried to do
$val= $_POST['val'];
$limit = 6 + $val;
echo $limit;
Im getting the result as 12. But what I want is
After first post result = 12
After second post result = 18
On and on...
NB:$_POST['val'] = 6;
session_start();
$limit = 6;
if(!isset($_SESSION['lastLimit'])) {
$_SESSION['lastLimit'] = 0;
}
if(!empty($_POST)) {
$_SESSION['lastLimit'] = $_SESSION['lastLimit'] + $limit;
$postedValue = $_POST['val'] + $_SESSION['lastLimit'];
echo $postedValue;
}
Because the web is stateless i.e. scripts do not remember anything that happened the last time a page/form was executed the receiver script does not remember anything from the last time it was run.
But dont panic, there is a way. Its called a SESSION and you can store data in the session which will then be available the next time this user connects to your site. In PHP you use it like this. The session is linked to this specific connection to a specific user.
receiver.php
<?php
// must be run at top of script, before any output is sent to the new form
session_start();
// did the form get posted and is the variable present
// or replace POST with GET if you are using an anchor to run the script
if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['val']) {
if ( isset($_SESSION['limit'] ){
// increment the limit
$_SESSION['limit'] += (int)$_POST['val'];
} else {
// initialize the limit
$_SESSION['limit'] = (int)$_POST['val'];
}
echo 'Current value of limit is = ' $_SESSION['limit'];
} else {
// something is not right
// direct this user to some basic page like the homepage or a login
header('Location: index.php');
}
You need an intermediate layer to store the value.
Available options:
1) Global static value
2) session
3) file
4) database
I would recommend global value or session, as they data you want to store isn't that huge and would meet the requirements easily.
I would not write the syntax to store it in session as a number of people have already mentioned it. I just wanted to clarify the problem scenario and possible solutions.
You can store $limti into global varibale .
global $val;
$val += $_POST['val'];
$limit = 6 + $val;
echo $limit;

Include different content based on variables

I'm using this method to display different content based on the variable that was passed down from my previous page.
<?php
if (isset($_GET['click'])) {
if($_GET['click'] == 'person'){
file_put_contents('person.txt', ((int) file_get_contents('person.txt')) + 1);
include 'resultperson.php';
} elseif ($_GET['click'] == 'text'){
file_put_contents('text.txt', ((int) file_get_contents('text.txt')) + 1);
include 'resulttext.php';
} elseif ($_GET['click'] == 'online'){
file_put_contents('online.txt', ((int) file_get_contents('online.txt')) + 1);
include 'resultonline.php';
}
} else {
include 'resulttext.php';
}
?>
Problem is, when I hit refresh, the file_put_contents() function will be executed again. It's just a way that I use to track how many times users have clicked that button.
How do I prevent the increment of the integer being injected upon refreshing the page?
Or if there's a simpler method doing all this?
Using a session is probably your best bet, unless you don't mind that when the user closes the browser and visits the page again it will be triggered.
// This will be set to true if the user has the session variable set
$clicked = isset($_SESSION['clicked']);
// Check if get variable 'click' is set, and that $clicked is false.
// If 'click is set and $clicked if false, the variable $click is set to the
// value of $_GET['click'] (for example 'person'). Other wise it will be set to false.
$click = (isset($_GET['click']) && !$clicked) ? $_GET['click'] : false;
// Set the session variable 'clicked' if it isn't set so that the next time
// the user visits, we'll know
if (!$clicked) {
$_SESSION['clicked'] = 1;
}
if($click == 'person'){
file_put_contents('person.txt', ((int) file_get_contents('person.txt')) + 1);
include 'resultperson.php';
} elseif ($click == 'text'){
file_put_contents('text.txt', ((int) file_get_contents('text.txt')) + 1);
include 'resulttext.php';
} elseif ($click == 'online'){
file_put_contents('online.txt', ((int) file_get_contents('online.txt')) + 1);
include 'resultonline.php';
} else {
include 'resulttext.php';
}
If you want to track where the user has come from, you can use the referer field of the http header.
If that's not an option, you could have your click link to a php page that registers the click, and then do a header("Location: x.php"); to the page that displays the content.
With your actual code, you can't prevent the increment of the integer on a page refresh.
The question is: does it matter? How important and accurate you want your tracker to be?
There is a way to attach the increment to the button click, which is to use AJAX. You can attach a handler to the button click event, which makes the appropriate AJAX call to the PHP script.
This is not simpler, but it is simple.
Both this solution and your actual one can't prevent a malicious user to make HTTP requests to call your PHP script, incrementing your counter at will...
This should work, and is simpler, and more easily extendable:
<?php
if (isset($_GET['click']) && isset($_SERVER["HTTP_REFERER"])) {
$click = $_GET['click'];
if (in_array($click, array('person', 'text', 'online')) {
file_put_contents($click . '.txt', ((int) file_get_contents($click . '.txt')) + 1);
include 'result' . $click . '.php';
}
} else {
include 'resulttext.php';
}
?>
You could use an ajax-call to trigger that operation. This way the url gets called "behind the scenes" without reloading the content. I recommend this option; using JQuery ajax it can be as simple as writing a onClick function like function clicked(){$.ajax("yourClickCounter.php");} and then adding <button ... onClick="clicked()">...</button> to the html. Of course, you would then have to have the clickCounting done in a separate PHP-file, but it has the advantage of not reloading all the content every time the button is clicked.
You could use a session variable like $_SESSION['has_clicked']. This requires that you start a session first, with session_start()
To diferentiate when a user visits the page from your previous page, rather than hitting refresh, look at the $_SERVER["HTTP_REFERER"] variable. That variable will contain the url of the previous page from when the user came, but in the case of a refresh, that variable will not exist as the user hasn't come from any page (he didn't click a link to get to your page) instead was the browser that sent the request.
If your previous page is called 'mypage.php' for this matter, then replace your following line:
if (isset($_GET['click'])) {
for this one:
if (isset($_GET['click']) && isset($_SERVER["HTTP_REFERER"]) && strpos($_SERVER["HTTP_REFERER"],'mypage.php')) {
that should do what you want.
Update:
Above solution will not work as when hitting Refresh on browser the page will maintain the same Referer value.

Creating hit Counter

I am trying to create a hit counter for my website and I have developed the following code for it. I have included the following code only in Codeigniter's main controller for my home page.
At first I thought the code was working fine but I just found that if I don't keep on browsing the pages then again go to the home page it doesn't update the data. I mean for example: If I go to my homepage for the first time then it updates the data, but after 10 seconds if I refresh the page it does't update the data. But if I keep refreshing it for 10 seconds then it works.
So could you please tell me how to get it update the data without having to keep on browsing the pages or refreshing the home page?
Thanks :)
function __construct() {
parent::__construct();
// Visitor Counter
if (!$this->session->userdata('timeout')) {
$out = time() + 10; // I will change it to $out = time() + 60*60; later
$this->session->set_userdata('timeout', $out);
mysql_query("UPDATE cane_visitor_counter SET visitor_stat = visitor_stat+1
WHERE id = '1'");
} else {
$timeout_time = $this->session->userdata('timeout');
if (time() > $timeout_time) {
$this->session->set_userdata(array('timeout' => ''));
$this->session->sess_destroy();
}
}
}
edit
What I am trying to achieve is when an user visits the webpage for the first time, I want to update my database. Within 10 seconds (for example purpose), if the visitor again visits the home page, the database will not be updated. But after 10 seconds if he again visits the home page, I want to update my database.
Thanks :)
Your code says "if there is no timeout in the session, update the count". You want it to say "if there is no timeout in the session, or there is but it's old, update the count".
function __construct() {
parent::__construct();
// Visitor Counter
if (!$this->session->userdata('timeout') || $this->session->userdata('timeout') < time()) {
$this->session->set_userdata('timeout', time() + 10);
mysql_query("UPDATE cane_visitor_counter SET visitor_stat = visitor_stat + 1 WHERE id = 1");
}
}
I'm not a CodeIgniter user, so I am assuming that you used its session facilities correctly; I just used them the same way.

Dynamic Text Using JavaScript & PHP?

I'm working on a little project, basically I have some text on my PHP/HTML page that is being echo'ed from a variable ($brief_string).
There is also a back, and continue button which basically subtracts or adds to another variable ($brief_page - which is pulled from my DB). The brief_string changes depending on the brief_page by using if statements. First problem I encounter is that when I hit continue (submit button) it resubmits/refreshes the page, causing my brief_page to reset back to 0.
So I'm thinking maybe I could use JS to hold the info and page variables and control the dynamic text, but then, how would I update my DB with the current page value via JS? Isn't it really easy to manually change/hack these values? I would preferably like my DB to be updated with the page number each time the use presses the back/continue button.
I would just like some advice really as I am a student trying to develop an interactive book like site (that uses a DB to save your current page).
Code:
<?
$brief_info = "brief info goes here";
$brief_page = 0; //< will soon be pulled off DB
if (isset($_GET['brief1Go'])) {
$brief_page = $brief_page + 1;
}
else if (isset($_GET['brief1Back'])) {
$brief_page = $brief_page - 1;
}
$breifController = "
<form action=\"".$_SERVER['PHP_SELF']."\" method=\"POST\">
<input type=\"submit\" name=\"brief1Back\" id=\"brief1Back\" value=\"BACK\" />
</form>
<form action=\"".$_SERVER['PHP_SELF']."\" method=\"POST\">
<input type=\"submit\" name=\"brief1Go\" id=\"brief1Go\" value=\"CONTINUE\" />
</form>";
if($brief_page == 0){
$brief1_info = "<b>Welcome Commander,</b> you are currently viewing the Mission Control Brief page, here you can view all your missions that you need to complete in order to advance through your prestiges. You will need to follow your briefs carefully in order to succeed. <br /><br />
";
}
else if($brief_page == 1){
$brief_info = "Okay, let me show you around the place ...";
}
else if($brief_page == 2){
$brief_info = "brief is on 2";
}
?>
Why not just use get vars entirely?
yes, start at 0 unless $_GET['page'] is set...
$brief_page = 0;
if(isset($_GET['page']))
$brief_page = $_GET['page'];
then only use links to your next and previous pages instead of some weird post thing.
Previous Next
where obviously the page numbers in the previous and next are just echoed from php
$prev = $brief_page - 1;
$next = $brief_page + 1;
The user specific things to store can easily be handled with sesisons, cookies or even other get vars if you want to introduce a horrible security hole. Your choice really.
I would definitely not do this via $_POST though. totally annoying. Go with all full on ajax if you want to do that. At least you won't pester the user with "are you sure you want to resubmit the form data" messages if they choose to refresh the page.

Categories