Using random name fields for input to fight spambots - php

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.

Related

Make an Input field blank

I have a newsletter form i kinda want to manipulate. I have no access to the backend, where it's specified that the newsletter form requires a name and an email adress. But i only want an email adress.
Can I somehow make the input field of the name pass an blank value/or an empty value so that it will still pass through the php?
Maybe (if you are lucky enough) using Injections.
There's an easy way, but less chance of success. Go to the Inspect Element of your browser and edit the following attributes of the relevant input field.
value=''
And if it has a
required
attribute remove it. But if they have validated the form from the back-end (95% possibility), you would be wasting your time.
Read these,
Injection Attacks

Know where request came from

I have multiple pages, say:
wedding catering
party catering
house warming catering
ETC
All pages use the same form
When the form is submitted the user gets directed to thank you.php which does the processing mail the form etc.
MY QUESTION
I would like to find out which page the submitted form came from, is there any simple way to do this?
The simplest ways are:
use the referrer header ($_SERVER['HTTP_REFERER'], with the typo missing R) or
use a hidden form field that differs from one page to another.
Whichever you use, just check the value on the page that processes the submission and go from there.
As frz3993 suggested, using $_SERVER['HTTP_REFERER'] is one option; however, I'd use this more for finding out what other sites users came from. Since this is your own site and you have control over the form generation, I would definitely go with a hidden field or something similar rather than trusting the user's browser to tell you which page submitted the form.
Never trust the client! :)
You can use here a hidden field for all different pages with all different values to trace the page.
for example you can use field name "came_from"
1.wedding catering
<input type="hidden" name="came_from" value="wedding catering">
2. party catering
<input type="hidden" name="came_from" value="party catering">
so on.

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.

PHP best practice for blocking form submissions with links?

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.

What is the point of input without name in HTML5?

In HTML5, an input without name is also valid
e.g.
<input type="text" id="user" />
But what is the point if I cannot access the form element in my backend PHP code?
Not all input is used server-side. In many cases it's used for form submission via AJAX. Additionally, a JavaScript app can make use of user input without ever needing to use a form.
Click the "link" button on any question or answer here on Stack Overflow, you will see an example of an <input> without a name or associated form.
Granted, this particular input is created with javascript - but it's pretty common to see an input field or textarea for copy/paste purposes, for one example.
..and it's also useful for basically anything to do with javascript.
One non-AJAX example I am currently using:
I have a spreadsheet for several dollar amounts to be filled in. I use an <input> field with no name to display the total amount of each column with javascript. On the server side, I don't need a "total amount" field coming through, and I sure as hell wouldn't trust it. The real total amount is calculated on the server side based on the other inputs, but we still show it in real time on the front end for the user.

Categories