PHP best practice for blocking form submissions with links? - php

Lately there's been a rash of bot posts to our forms for the purpose of posting links (backlink bots).
We've added reCaptcha only to find it's been cracked and the bots can figure out the proper response.
We've added a Honeypot field but find these submissions are posting without using the form. Looks like the first catalog the form for required fields then submit only those, crack the captcha and post their spam to a comment field.
I'm sure they are blindly posting to any forms thinking they will be a blog comment so our contact us forms are getting caught up in the mess.
Next step is to block the submission if the contents contain a link. This seems like the best logical method as it goes for their goal as the trigger to block.
Question: Would looking for url characters be the best method to isolate a spam submission or could FILTER_SANITIZE_URL be used as a hook to trigger the deny?

Just expanding on my comment as a few people seemed to think it had merit.
There are several approaches to this.
I would suggest adding a nonce to your forms as a hidden field. When the user requests a form from your site a nonce is created that has to be returned with the form by that user for it to be a valid submission.
This answer gives more information about that. How to create and use nonces
You also say about blocking all entries that contain any html. a simple method of doing that is
if (strip_tags($string) !== $string)
// Drop post as it had html in it

if (strstr($data,'http://')) {
echo "contains link";
}

You can pass some checksum along with the form data to validate it.
On client-side, add an event listener on form's "submit" event, where you, for example, calculate sum of length of all form fields, and then put it in hidden field.
On server-side, calculate the checksum the same way, and compare it with what you got in that hidden field.
Sum of lengths is the simplest way of checking, but it would cut off all automated bots, that are not targeting exactly your site. But if that would not be enough, you can create more complex algorithm to calculate checksum, and then obfuscate that javascript, so it would take a lot more effort to adapt these bots for your protection system.

Related

Why use hidden field to detect form submission?

I've been reading PHP form handling tutorials, and they suggest using a hidden field in the form so PHP can use something like IF ($_POST['hidden_field'] == whatever to detect whether the form was submitted or only displayed.
But after getting XDebug working with Notepad++ and stepping through the code and observing the variables, it's not clear to me why we can't just go IF ($_POST['submit_button'] == 'Ok') and do away with the hidden field entirely.
After all, there doesn't seem to be a time when the hidden field is set without the other form fields being set too (even if they're empty). The first time through, when the form is being displayed and before it has been submitted, the $_POST variable already exists, but it is empty. I suppose we could also use IF (!empty($_POST)) to see if the form has been submitted?
Is there a special case I'm missing where the hidden field is necessary to detect form submission?
EDIT: Ok, the special case I was missing and that requires the hidden field appears to be this. http://www.vbforums.com/showthread.php?562749-PHP-Checking-if-a-form-has-been-submitted-the-correct-way It seems that if you hit Enter to submit the form, the $_POST variable will not include the value of the submit button. Chrome doesn't seem to behave that way but maybe other browsers do.
Is there a special case I'm missing where the hidden field is
necessary to detect form submission?
To detect the form submission you don't need a hidden field in the form but some times it's used as a spam protection. For example, if you put a hidden field in your form, like
<input type="text" name="humans" id="humans" class="humans" />
You may use a css class to hide the filed like
.humans { display: none; }
and when you check the form submission, you may also check if the field is empty or not, like
if(!empty($_POST['humans'])) {
// it's spam
}
else {
// it's human
}
Because, bots/spammers (using automated script) can submit the form and basically the script tries to fill up all the fields and doesn't know about the hidden field that you have put to catch it and this way you may determine whether it's submitted by a human or bot. You may read this article for more information and better understanding of spam blocking..
No, you have the right idea.
I wouldn't recommend doing this, however - sounds like whoever wrote the tutorial is a bit of a newbie. ;) If you're using POSTs for your forms already, I'd stick with the more traditional (and simpler) method of detecting whether the form was submitted or if someone is just viewing the page by means of the HTTP method ($_SERVER['REQUEST_METHOD'], as "GET" or "POST" in PHP).
Why implement a [hidden] field to check if the form is submitted when you must have other fields to check by if you have a form in the first place.
Other than checking if submitted, the hidden field is redundant, and so just pointless extra code.
If you have multiple forms on a page, name the submit button, if only one, just check if $_POST isset(), then go about validating data, etc etc
You can use !empty($_POST) instead, but I try to avoid this (depending on scenario) as I like to tell the user they did not enter anything, otherwise user clicks submit and it just hows them the blank form again.
Sure they would likely know they're messing around, but perhaps they thought they typed something, for numerous potential reasons.
Always good to keep users appraised, especially of any potential mistakes on their part.
There is no difference in using a hidden field just to check that the form has been submitted.
But let's say you want to dynamically post a value that there is no reason to show in the form.
For example you have an array $user that holds all the data of a user. The user submits the form, and you pass as a hidden field $user['id'] to work with their id after the submission.
Or you find their language through IP or whatever and pass it as a hidden field to show a message in their language.
Although I don't do this myself, I would say that it can be useful to undermine curl or other methods of accessing the site outside of a regular browser - of course the hidden field has to differ with every request.
Yes, there are multiple use of hidden field to validate a submit
as you mentioned, differentiating between form view and submission.
as #kingkero mentioned, a way to block form auto submissions by robots.
and in case of editing an existing record
a primary key is required to locate original record, and it should be hidden so user can't change it
you can save old data somewhere in server side before sending to browser and then send a reference key to that data as hidden field, later it can be used to compare old and new data to determine what has been changed.
in multi-user system, if more then one user select to edit and save a specific record at the same time then there is chance that they can overwrite each-other!! to prevent this situation a hidden field can be used to determine and notify user if selected record has been changed during form load and submit period.

Using random name fields for input to fight spambots

I'm considering using random input names for registration form. It would be done this way:
User requests register form site.
Create random names for input fields and save them to user's session.
Render form and display it to the user.
I just wonder if that method gives me anything. If session driver is a cookie - it's
encrypted and secured in the best possible way using third party library which I consider as save enough. If user don't except cookies I can refuse registration.
To remove cookies as potential security risk I can store sessions in database. This seems more secure but also might overload the server(?).
My question is quite simple. Is there any sense to implement such feature?
The standard approach is to have a hidden text field. That is a field with type=text, but with CSS rules applied to it so that it's invisible.
markup:
<input type="text" name="put_some_innocuous_name_here" class="some_innocuous_css_class_name_here" value="" />
CSS:
input.some_innocuous_css_class_name_here {
display: none;
}
PHP:
if ((isset ($_POST ['put_some_innocuous_name_here']))
&& ($_POST ['put_some_innocuous_name_here'] != ''))
{
throw new Exception ('Suspected bot!');
}
The way this works is quite simple. A normal user will never see your hidden text field because CSS rules will keep it hidden. therefore a real user will never fill it out.
However, most spambots aren't aware of CSS. They just parse the form markup and they see a text field that appears to need filling out. So they fill the field out with some random data. Because a form field that should never be seen by a normal user has been filled out, this means you're probably dealing with a bot.
Don't use input type=hidden for this, because most spambots are smart enough to notice them and ignore them.
A little late but I have created an class file which does exactly what you need you can find it here.
You just need to pass the name of the form through a function example.
<input type="text" name="<?php echo $obj->DynamicName("fieldName")?>"/>
and once the form is submitted it will populate $_POST['fieldName'] with appropriate data as soon as you create its object.
Try checking the IP against known spammers lists, it's very effective. Good examples would be Botscout and Spambusted. I've tried both, and they reduced my spammer bot registrations.

How to use form information to auto populate a form on another webpage

I am trying to figure out a way that I can populate form fields on webpage for my users much like password managers do. The problem is that I am not the owner of the second webpage. I thought about using javascript with iframes but that doesn't work. I've tried using php to replace the form information adding values saved from my previous form. But I need to add info on a second form after the first one is submitted. After I submit the first page I am off my page and can't change anything else. So I'm kinda out of ideas and my knowledge is limited. Any ideas or input would be greatly appreciated. Thank you for your time and effort.
Cannot be done because of the SOP (same origin policy) enforced on JavaScript code. An alternative would be through XSS, other via a bookmarklet, and as a last choice trough a GreaseMonkey script.
GreaseMonkey may be your best choice, if the data to be filled in is from your website. Best choice because GreaseMonkey scripts can perform cross domain ajax requests.

What is the best way to identify which form has been submitted?

Currently, when I design my forms, I like to keep the name of the submit button equal to the id of the form. Then, in my php, I just do if(isset($_POST['submitName'])) in order to check if a form has been submitted and which form has been submitted.
Firstly, are there any security problems or design flaws with this method?
One problem I have encountered is when I wish to overlay my forms with javascript in order to provide faster validation to the user. For example, whilst I obviously need to retain server side validation, it is more convenient for the user if an error message is displayed inline, upon blurring an input. Additionally, it would be good to provide entire form validation, upon clicking the submit button.
Therefore, when the user clicks on the form's submit button, I am stopping the default action, doing my validation, and then attempting to renable the traditional submit functionality, if the validation passes. In order to do this, I am using the form.submit() method but, unfortunately, this doesn't send the submit button variable (as it should be as form.submit() can be called without any button being clicked). This means my PHP script fails to detect that the form has been submitted.
What is the correct way to work around this? It seems like the standard solution is to add a hidden field into the form, upon passing validation, which has the name of form's id. Then when form.submit() is called, this is passed along in place of the submit button. However, this solution seems very ungraceful to me and so I am wondering whether I should:
a) Use an alternative method to detect which form has been submitted which doesn't rely rely on passing the submit button. If so what alternative is there? Obviously, just having an extra hidden field from the start isn't any better.
b) Use an alternative Javascript solution which allows me to retain my non-Javascript design. For example, is there an alternative to form.submit() which allows me to pass in extra data?
c) Suck it up and just insert a hidden field using Javascript.
UPDATE:
I've accepted the correct answer but I just wanted to clarify my mistake here so it would be more helpful for others. I use Mootools and I very naively believed that when I used addEvent('submit' ...) I needed to immediately call event.stop() in order to prevent the from from being submitted. Actually this is not the case and I can just call event.stop() only if validation fails. Otherwise, the default submit gets fired, as usual, and using form.submit() becomes completely unnecessary.
You could send the forms to different handlers with action=file1.php and action=file2.php.
Are they processed using a bunch of the same code? Put that into separate files, include the commonalities, and write the unique bits in each of the handling files. Don't hack, organize.
For Javascript validation, don't halt the default action then resume, instead do this:
if (validation != valid) {
return false;
}
That way if JS is turned off or the validation fails, the form action/event is intact and it behaves as expected, otherwise it bonks. And certainly, certainly retain server-side validation. That's the "real" validation, the client-side is only to please the user and save them time. Never rely on it for YOUR sake.
You can customize the action of the form to add a get key/value; such as action="formhandle.php?formid=10"

Form framework for inputs specified by custom popup window

I have a PHP based form. For many of our inputs, the user clicks an html which created a custom popup window with a "mini-form". When the user clicks on the submit button, the values from the "mini-form" are sent to the main form to hidden inputs using JavaScript. This can become complicated to do, especially with validation and other complications. I know there are a million PHP frameworks for forms, but I can't find one to deal with these situations.
Does anyone have advice?
My understanding is that you are opening new form using var win = window.open() now using the win reference you might be populating the actual forms data. This is old good approach which is been working well from long time.
If this is correct Then I think that if you would really want to do it in better way you should start with JQuery UI.

Categories