Cooldown on Post in PHP - php

I have a really basic PHP chat system. Only thing post do is adding a line with $user and $message to log.html.
But users can spam with holding enter or pressing enter multiple times. And that causes lag in website.
I want to make a cooldown system for like 0.3 seconds. If it's in cooldown, don't let user post or disable the input for 0.3 seconds.
How can I make this?
Here, my code :
index.php contains 2 things. "log.html" and these codes
<form name="message" action="">
<div class="input-group dropup" id="bottom">
<input type="usermsg" type="text" id="usermsg" maxlength="65" autocomplete="off" class="form-control" placeholder="Type your message here.">
<span class="input-group-btn">
<button class="btn btn-success" type="submit" name"submitmsg" id="submitmsg">Send</button>
</span>
</div>
</form>
And the post.php contains these codes
<?
session_start();
if(isset($_SESSION['name'])){
$text = $_POST['text'];
$sp = fopen("player_log.html", 'a');
fwrite($sp, "<div class='msgln'>[" .date("Y-m-d"). "-".date("g:i A"). " | " .$_SERVER['REMOTE_ADDR']."] <b>".$_SESSION['name']."</b>: ".stripslashes(htmlspecialchars($text))."<br></div>");
fclose($sp);
// SOME str_replace CODES FOR EMOTICONS, BANNED TEXTS ETC..
$fp = fopen("log.html", 'a');
fwrite($fp, "<div class='msgln' style='color: #BDBDBD;'><b style='color: #FFBF00;'>[Player] ".$_SESSION['name'].":</b> ".$finaltext."<br></div>");
fclose($fp);
}
?>

You could try using the setTimeout() function in JavaScript. When enter is pressed, disable the user from entering another message (I can't comment on how to do this, as you have posted none of your code). Then use the setTimeout() function to enable the input after x amount of seconds (below shows an alert after 3 seconds):
setTimeout(function(){
alert("Hello");
}, 3000);
If you want more help, expand on your question and show us some code.
Having read through the code you have posted, it could be worth doing what others have suggested - check if the content is empty and don't post it. However, this still won't stop users spamming with one letter replies. If you want to users from quickly entering messages and posting them, I believe the timeout would work best. If you want to only stop users from holding down enter, checking for empty messages would probably be better. The best solution (in my eyes) would be to use both techniques as it would stop users from quickly spamming and stop users just entering blank messages.

Disabling the input is not a good solution. It will disrupt the user experience and users gonna hate you for that.
A better approach would be to do nothing if the message is empty or contains spaces or banned characters only.

When your Users enters a message and you recieve it, just add a timestamp to a session variable. When the User sends a message again, check the timestamp in the session, with the current timestamp.
http://php.net/manual/de/datetime.gettimestamp.php

Change this
$text = $_POST['text'];
To this
$text = $_POST['text'] || exit();
This way if a user posts nothing, nothing happens.

Related

Saving form element to a text file on server

I am having trouble extracting data from a form. I would like to save email address to a text file to the local server. The user will go firstly to this site (picture),
website
They will type in their email address and a wireless key (controlled by Unifi) and then hit submit. At that point, I would like the email they entered to be saved to a text file. The connect button also authenticates the user with Unifi and they are able to connect to the guest wireless.
The code I have so far is:
<!-- Email Input -->
<fieldset class="large-text">
<p class="form-element">
<label for="email" class="fieldname">Email</label>
<input id="emailcontainer" method="post" name="emailtxtbox" class="textInput" value="" autocomplete="on" input type="email" required placeholder="Enter your email"/>
</p>
</fieldset>
<!-- End of Email Input !-->
This creates the email textbox entry that you see above in the picture.
The below code is the php execute, that will (hopefully) grab the email, and then save it too the text file:
$getemail = $_GET["emailtxtbox"];
$emailtxtbox = $_POST["emailtxtbox"];
if($getemail = "connect") {
$targetFolder = "/emailcollate";
file_put_contents($targetFolder."mytext.txt", $emailtxtbox);
}
As you might of guessed, I have no skill in php or html, so please keep it simple. I have played around the above codes a lot, so some of it may have different names etc. I would appreciate any help!
Does anyone think it would be better to use the file_put_contents() function to do the above?
ok, it has been a long time since i have worked with php, but i will do my best.
the way I would troubleshoot this is make sure the php page actually ran, easily done with:
var_dump("this page ran");
after the page has run, dump the two variables out to the page to confirm that the page has received them and has accurately change them to a variable.
next, in your if statement, dump some random text to make sure the if statement has run.
otherwise, make sure you know where the php file is trying to save to, may have to use this instead:
file_put_contents("/emailcollate/mytext.txt", $emailtxtbox);
the file_put_contents() function should work fine
In PHP $GET is used for picking up parameters in your site's URL, and $POST is used for gathering form values that are submitted to your page.
In your case you're getting the value for $getemail from the URL of your page, so for $getemail to have a value the URL for your site should resemble
www.yoursite.com/?emailtxtbox=connect
Additionally you need to add an extra equals sign in your if statement, like so:
if($getemail == "connect") {
The double equals is a comparator used for comparing two values against each other, rather than a single equals which is used for assigning a value to a variable.
Your file_put_contents looks ok, but like user6063785 has suggested try running that block of code outside of the if statement to see if the file is being written to. You may need to ensure that PHP has permissions to write to the file.

redirect to current page if user clicks back or refreshes the page

Sorry I have posted this question and I googled it alot still Im unable to solve this
I have a php page that has a form and when user clicks refresh or F5 it creates duplicate values in the database and also a message is alerted to the user, indicating resubmitting may insert duplicate values in database.My boss dont want that alert box of the browser to user and also insertion of duplicate values into the database
I know its header(). I read lot of header() in php manual and also server_name functions but still I tried in many ways putting in the top but cant solve it. its very important. can anyone please help me with a sample of code explaining the way to do.any help is greatly appreciated.
<form method="post" action"demo.php">
<input name="fname" type="text">
<input type="submit" value="submit">
</form>
demo.php
<?php
$firstname = $_POST['fname'];
?>
Tell me what should i add in the demo.php page to stop it from submitting the form again and again and also if user clicks back button on the browser it should not direct to the previous page , it should still redirect to current page.
So if user clicks refresh or back button it should redirect to current page only and should not insert any duplicate values and also alert box should be disabled.Please explain me what to do here, im in deep help.Thanks
There's lots of things wrong with your code, and lots of ways to mitigate the impact.
First, why are you creating duplicate entries?
In addition to the problem of bad data is also implies that your site is vulnerable to CSRF. Go read up on how to prevent CSRF with single-use tokens.
If you've got performance problems with your site, then users will often click on the submit button multiple times. While addressing the duplicate submission problem on the database, use javascript to disable the submit links on the page and provide visual feedback that the page is doing something.
Redirects are not the way to solve the problem.
My boss dont want that alert box of the browser
Are you talking about the duplicate post alert? While you can get around this using PRG, that creates other problems.
You must post a unique id (session_id) and save it in the database.
When your registration, test if the session_id is already present. If so, send a message to THE USER. "You have already post out this form"
The code:
<?php session_start; ?>
<form method="post" action"demo.php">
<input name="fname" type="text">
<input type="submit" value="submit">
<input type="hidden" name="session_id" value="<?php echo session_id();?>">
</form>
demo.php
<?php
//test session_id in database
$session_id = session_id();
mysql_connect('localhost','xxx','xxx');
mysql_select_db('xxx');
$return = mysql_query("SELECT COUNT(*) AS nb_data FROM TABLENAME WHERE session_id='".session_id()."'");
$data = mysql_fetch_assoc($return);
if ($data['nb_data'] == 0){
echo 'Your message';
}
else{
$firstname = $_POST['fname'];
//.....
header('location:xxx.php')?
}
?>
I would use php header function to replace the current location so if the user clicks refresh, it won't repost the information and a session to store the posted value and check for resubmissions.
demo.php
<?php
session_start();
if($_POST)
{
if(!isset($_SESSION[fname]))
{
//database queries here
}
$_SESSION[fname] = $_POST['fname'];
header('location:demo.php', true); //true replaces the current location
}elseif(!issset($_SESSION[fname])){
header('location:form.php');
}
$firstname = $_SESSION[fname];
?>
form.php
<form method="post" action"demo.php">
<input name="fname" type="text">
<input type="submit" value="submit">
</form>
You need ON DUPLICATE KEY , this will update the record instead of creating a copy of it :
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
so it wouldn't matter if they hit refresh or resubmit, if the record existed already it would just get updated.
The solution will be to redirect the page after database operations like insert, update and delete
pageName: test.php
if(isset($_REQUEST['deleteBtn']))
{
$emp_id=$_REQUEST['emp_id'];
$count=mysql_query("delete from employees where emp_id=$emp_id");
header("location:test.php");
}
This way if you click F5 or back button the form data will not get posted again.
What you want is to embed a session id in your form when you create it, and to track that session id on the server. Then, when the form is submitted and you are processing the form on the server, if the form was submitted more than once, you can overwrite the first submission in your database, or respond with an error message, or whatever. (Show the popup only on the first submission, whatever.)
An easy way to do this is to generate a session id, send it as a hidden field in the form, and when the form is submitted store the session id in your database with the constraint that the session id be unique.

Need Help Taking User Submitted Value and Generate Unique URL from PHP Form

In the script below, you will see a value that is submitted in the form titled "shorturl." Ultimately I would like to take that value and use it to generate a unique URL that displays all of the submitted data from the form.
Here is the form where a user will submits the data:
<html>
<body>
<p>Required fields are <b>bold</b></p>
<form action="contact.php" method="post">
<p><b>Author's Name:</b> <input type="text" name="author" /><br />
<p>Company Name: <input type="text" name="company" /><br />
<p>Address:<br /><textarea name="address" rows="5" cols="40"></textarea></p>
<p>Phone Number: <input type="text" name="phone" /><br />
<b>Title:</b> <input type="text" name="title" /><br />
<p><b>One Word Description:</b> <input type="text" name="shorturl" /><br />
<p><b>Full Description:</b><br />
<textarea name="comments" rows="10" cols="40"></textarea></p>
<p><input type="submit" value="submit"></p>
<p> </p>
</form>
</body>
</html>
The next bit of code is the contact.php page that will output the user data:
<?php
/* Check all form inputs using check_input function */
$author = check_input($_POST['author'], "Enter your name");
$company = check_input($_POST['company']);
$address = check_input($_POST['address']);
$phone = check_input($_POST['phone']);
$shorturl = check_input($_POST['shorturl'], "Provide a single word description");
$title = check_input($_POST['title'], "Write a title");
$comments = check_input($_POST['comments'], "Provide a full description");
/* Functions we used */
function check_input($data, $problem='')
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
if ($problem && strlen($data) == 0)
{
show_error($problem);
}
return $data;
}
function show_error($myError)
{
?>
<html>
<body>
<b>Please correct the following error:</b><br />
<?php echo $myError; ?>
</body>
</html>
<?php
exit();
}
?>
<head>
<title><?php echo $_POST['title']; ?></title>
</head>
<body>
<p>
<b><?php echo $_POST['title']; ?></b><br>
Created by:<br>
<?php echo $_POST['author']; ?><br>
<?php echo $_POST['company']; ?><br>
Contact: <br>
<?php echo $_POST['phone']; ?><br>
<?php echo $_POST['address']; ?><br>
Flyer Description: <br>
<?php echo $_POST['comments']; ?><br>
</p>
</body>
</html>
As you will see if you run this form, the function is pretty basic. Here is where I need the assistance. In the initial form the "shorturl" value is taken. The function of the shorturl value is as follows:
If this form was hosted on examplesite.com, then I would ultimately like for the form that is created to be available with submitted answers at examplesite.com/shorturl
First of all, how do I verify that this is in fact a single word via PHP? If a user submits the shorturl value as "House" then I need the form to return the value as true, but if the user submits "Big House" then the value is false and they need to alter the value to something that is acceptable such as "BigHouse"
Secondly, I need to verify that the shorturl value is unique to the site. In other words, once a shorturl has been used, that value needs to be sent to the MySQL database so that it will not be replicated by another user. To continue our example, if someone already had "House" as their shorturl value then the full URL of examplesite.com/House is already taken. Then if a new user comes and tries to use "House" the submission will produce an error message that says the name is taken.
And finally, how do I get all of this information to auto-generate a unique webpage with the form results? For an example let's continue examplesite.com/House
Right now, when a user submits the form, the data is displayed on examplesite.com/contact.php. How do I generate a URL which would display the form data and be unique as defined by the shorturl and be viewable to a third party site visitor without submitting new data?
Wow. I hope that all makes sense.
I know there are several questions in here, so if you can only assist with one step that is fine. If you can tackle this entire issue then more power to you :)
I have done a fair amount of research on this and I am thinking that the first 2 questions should be able to be solved with PHP, but the third might involve a mod_rewrite function of some sort. I cannot thank you enough for getting this far with my query and many many thanks if you can provide a solution.
This should do a good job of verifying $shorturl:
if (preg_match('/[^a-z0-9]/i', $shorturl)) {
// $shorturl contains characters other than just numbers or
// letters such as a tab, space, or special chars you probably don't want
}
As for making sure the url is unique:
if (!mysql_num_rows(mysql_query("SELECT id FROM contact WHERE url = '$shorturl' LIMIT 1")) {
// it is unique, yay
}
And you would insert the urls like so:
mysql_query("INSERT INTO contact (url) VALUES ('$shorturl')");
As for autogenerating the content, that shouldn't be that tricky. First, you will need to insert all the form data into the database, I would do this at the same time you insert the url. For dynamically retrieving the data, (using such a short url) you will need to do a tiny bit of .htaccess modification.
Here is an example of what your .htaccess might look like for a user to be able to go to domain.com/shorturl while the actual scripts being ran (and what they will see) are at domain.com/contact.php?short_url=shorturl
RewriteEngine on
# don't rewrite if the file exists
RewriteCond %{REQUEST_FILENAME} !-f
# don't rewrite if the directory exists
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ contact.php?short_url=$1
At this point the rest is just capturing the GET variable as $_GET['short_url'] within contact.php (or anywhere you want this script to reside, as long as you change the RewriteRule accordingly) and returning the rest of the the information you captured using database queries, maybe something like:
$short_url = mysql_real_escape_string($_GET['short_url']);
$sql = "SELECT * FROM contact WHERE url = '$short_url'";
$user_data = mysql_fetch_array(mysql_query($sql));
extract($user_data);
// with extract, all of $user_data's keys are now variables and their respective values
// are contained within those variables
// $user_data['company'] now becomes simply $company, for example
echo "Company: $company";
// etc...
I hope this helps :)
I agree with Wylie. I also agree with you (Presto) that your post is a little hard to get at times x). Either way, I will try to answer your questions as fully as possible, based on what I understand what you mean.
1) The best way to check if it's a single word is by checking word delimiters. The most typical word delimiter is the space, but things like hyphens, commas, and periods are obviously delimiters as well. In your case, the best way to determine what to allow is to consider what will correctly parse as a URL and what won't. For example, you should not allow the plus sign (+) to be used.
You can do several things to prevent these kinds of breaks. You can either correct it, or refuse it. In other words, you can either replace/ remove 'illegal characters' without any additional interaction/ approval of the user, or you can simply bounce it back to the users stating that it is invalid and that they will need to fix it. You can do this at a server level (PHP) or at a client and server level (Javascript for direct check, and PHP as a fail safe). Depending on how tolerant you'll be, and whether you will fix or refuse a string, you should either use a str_ireplace() type of function, or you should use regexp (preg_match()). There is, at this point, no way for me to tell you which one to use.
2) I can't say what's the best way to do this, as this very strongly depends on your system setup, but if it would make sense in your system, I would use MySQL for this task and store the names of the 'page directory' in a table with at least two rows: id and shorturl (as you refer to it). The id should be the primary key and you'll use this id to identify (/ JOIN) data that is needed to be displayed on the web page. The shorturl column should be index as 'UNIQUE'. This way, if you try to insert another value in that table column, MySQL will throw you an error (I believe errno 1169). Because of this, you can simply run the insert query after a user has submitted your form (and your PHP code has checked it) and you can then just check for that errno to see if the name has been used before.
3) Depending on how you set up your web server, you can do several things. Writing a mod_rewrite file is of course possible (and fairly easy, as you can build it in PHP and just write it to your web server). Another way you can do it is to fetch the shorturl that the visitor typed in his/ her address bar and then cross check that with your database table (like the one from point two above here) and then do an internal redirect, using the header() function in PHP.
Let me know if that was of any help, or if things are still unclear.

php secure comment logic?

Ok, this might be obvious but its not clicking quite yet. I am creating a forum/blog esque app.
I grab the posts from the database rather securely but commenting is beginning to be a little more difficult. (I could just be paranoid, right?).
How do I add a comment without exposing the id of the parent message? (like in a hidden form field or query string, or something).
I guess I am a bit paranoid that someone might go into the code with firebug or something and change the hidden form field value to something else before submitting. I guess I would have to make sure the user has permission to comment to that particular post/category?
Things to note :
The user is already logged in.
Its not a public post
I would recommend that you setup your database like so:
Comments
---------
id
encodedID
authorID
parentID
message
Then, for the form field have two hidden values, one will be the encodedID, and the second will be a hash that you make. I would recommend the hash to be:
<?php
$hash = sha1(md5($encodedID . $userID . $_SERVER['REMOTE_ADDR'] . "abc1234"));
?>
Then, when the user submits the form, validate that the hash is valid for the specific encodedID and user. Here is a brief code write up:
<?php
if(isset($_POST['submit']))
{
//Get the variables and all and sanitize the input of 'message'
if(sha1(md5($_POST['value1']. $userID . $_SERVER['REMOTE_ADDR'] . "abc1234")) == $_POST['value2'])
{
//User is valid.
}
else
{
//Invalid user.
//Document this.
}
}
$value1 = $encodedID; //Grab this from your database
$value2 = sha1(md5($value1 . $userID . $_SERVER['REMOTE_ADDR'] . "abc1234"));
?>
<form method="post" action="comment.php">
<input type="text" name="message" />
<input type="hidden" name="value1" value="<?php echo $value1; ?>" />
<input type="hidden" name="value2" value="<?php echo $value2; ?>" />
<input type="submit" name="submit" value="Comment" />
</form>
Edit: Just a small tip, but I would recommend that you change value1 and value2 to something abstract, don't call it encodedID or anything like that, just so that it confuses any users that will attempt to try and break it.
And yes md5 and sha1 are not completely secure, but for this case it will work since you want to be able to process the comments fast and efficiently.
That might be an overkill but if you really want to hide the post_id of the current message then you should consider using session. So instead of using something like this on your form:
<form action="/postcomment.php" method="post" >
<input name="post_id" type="hidden" value="123" />
<textarea name="message"></textarea>
</form>
Reduce it to something like this:
<?php $_SESSION['post_id'] = '123'; ?>
<form action="/postcomment.php" method="post" >
<textarea name="message"></textarea>
</form>
Of course this is "yucky" coding but at least you get the idea.
Oh, don't forget to validate EVERYTHING on postcomment.php. Also escape ALL string input values and make sure all numeric inouts are numbers indeed (multiply them by one?).
[EDIT: Due to insistent public demand, may I, if you please, amend the aforementioned:]
Instead of:
<?php $_SESSION['post_id'] = '123'; ?>
Generate a form id:
<?php $_SESSION['form_id'] = $_SESSION['user_id'].'_'.md5(time()); ?>
Then generate the unique post_id:
<?php $_SESSION[$_SESSION['form_id'].'_post_id'] = '123'; ?>
After submitting get the post_id:
<?php $post_id = $_SESSION[$_SESSION['form_id'].'_post_id']; ?>
you could assign the form an "id" as a hidden field and create a database table to track form ids and their associated post ids, that way when the form gets submitted you could check the post id in the db without ever sending it to the client based on the form id that is returned with the post
You're asking the wrong question here: instead of being concerned about the user getting some internal ID that means nothing outside your application, your primary concern should be about keeping them from doing anything unpleasant with it.
Imagine I just started sending POST requests to add a comment for every ID between 1 and 10,000. I'm sure to hit a real post sooner or later.
Rule #1 about writing secure web applications: Don't trust the user.
In other words, yes, you should check to make sure that they have permission to comment when you receive the results back from the from.

how do I verify this value?

entering total value of two numbers in a text box to prevent spam
<?php
$rand = rand(2,9);
$rand1 = rand(2,9);
echo $rand." + ".$rand1;
?>
<span class="stred">*</span>
</label>
</td>
<td>
<div class="input-container">
<input name="randm" class="intext" id="county" type="text" />
</div>
How do I verify this value of both in a POST method??
There is nothing to verify in your code. You cannot compare the received value, because you did not keep the originals. You throw away $rand and $rand1 in the snippet that you have shown.
You need to keep them in the session (don't forget session_start() beforehand) like so:
$_SESSION["rand"] = $rand + $rand1;
Then you might be able to do this when you receive the form:
if (strlen($_POST["randm"]) && ($_POST["randm"] == $_SESSION["rand"])) {
$_SESSION["rand"] = ""; // unset afterwards to prevent replays
I would use a CAPTCHA instead. With math problems, you still have to display the equation for users to solve, which opens the door for a spammer to write a script to parse the operands from your HTML, solve the math problem, and submit a POST request containing the correct answer. Automating such a script would allow for the continuous misuse of your form, a scenario which is actually not as unlikely or difficult to accomplish as one might think.
reCATCHA is a good option should you choose to go the CAPTCHA route.

Categories