How to prevent robots from automatically filling up a form?
I actually find that a simple Honey Pot field works well. Most bots fill in every form field they see, hoping to get around required field validators.
http://haacked.com/archive/2007/09/11/honeypot-captcha.aspx
If you create a text box, hide it in javascript, then verify that the value is blank on the server, this weeds out 99% of robots out there, and doesn't cause 99% of your users any frustration at all. The remaining 1% that have javascript disabled will still see the text box, but you can add a message like "Leave this field blank" for those such cases (if you care about them at all).
(Also, noting that if you do style="display:none" on the field, then it's way too easy for a robot to just see that and discard the field, which is why I prefer the javascript approach).
What if - the Bot does not find any form
at all?
3 examples:
- Insert your form using AJAX
- If you are OK with users having JS disabled and not being able to see/ submit a form, you can notify them and have them enable Javascript first using a noscript statement:
<noscript> <p class="error"> ERROR: The form could not be loaded. Please enable JavaScript in your browser to fully enjoy our services. </p> </noscript>
Create a
form.html
and place yourform
inside a<div id="formContainer">
element.Inside the page where you need to call that form use an empty
<div id="dynamicForm"></div>
and this jQuery:$("#dynamicForm").load("form.html #formContainer");
- Build your form entirely using JS
// THE FORM
var $form = $("<form/>", {
appendTo : $("#formContainer"),
class : "myForm",
submit : AJAXSubmitForm
});
// EMAIL INPUT
$("<input/>",{
name : "Email", // Needed for serialization
placeholder : "Your Email",
appendTo : $form,
on : { // Yes, the jQuery's on() Method
input : function() {
console.log( this.value );
}
}
});
// MESSAGE TEXTAREA
$("<textarea/>",{
name : "Message", // Needed for serialization
placeholder : "Your message",
appendTo : $form
});
// SUBMIT BUTTON
$("<input/>",{
type : "submit",
value : "Send",
name : "submit",
appendTo : $form
});
function AJAXSubmitForm(event) {
event.preventDefault(); // Prevent Default Form Submission
// do AJAX instead:
var serializedData = $(this).serialize();
alert( serializedData );
$.ajax({
url: '/mail.php',
type: "POST",
data: serializedData,
success: function (data) {
// log the data sent back from PHP
console.log( data );
}
});
}
.myForm input,
.myForm textarea{
font: 14px/1 sans-serif;
box-sizing: border-box;
display:block;
width:100%;
padding: 8px;
margin-bottom:12px;
}
.myForm textarea{
resize: vertical;
min-height: 120px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="formContainer"></div>
- Bot-bait input
- Bots like (really like) saucy input elements like:
<input type="text" name="email" id="email" placeholder="Your email" autocomplete="nope" tabindex="-1"
They wll be happy to enter some value such as
`[email protected]`
- After using the above HTML you can also use CSS to not display the input:
input[name=email]{ /* bait input */ /* do not use display:none or visibility:hidden that will not fool the bot*/ position:absolute; left:-2000px; }
- Now that your input is not visible to the user expect in PHP that your
$_POST["email"]
should be empty (without any value)! Otherwise don't submit the form. - Finally,all you need to do is create another input like
<input name="sender" type="text" placeholder="Your email">
after (!) the "bot-bait" input for the actual user Email address.
Acknowledgments:
Developer.Mozilla - Turning off form autocompletition
StackOverflow - Ignore Tabindex
What I did is to use a hidden field and put the timestamp on it and then compared it to the timestamp on the Server using PHP.
If it was faster than 15 seconds (depends on how big or small is your forms) that was a bot.
Hope this help
An easy-to-implement but not fool-proof (especially on "specific" attacks) way of solving anti-spam is tracking the time between form-submit and page-load.
Bots request a page, parse the page and submit the form. This is fast.
Humans type in a URL, load the page, wait before the page is fully loaded, scroll down, read content, decide wether to comment/fill in the form, require time to fill in the form, and submit.
The difference in time can be subtle; and how to track this time without cookies requires some way of server-side database. This may be an impact in performance.
Also you need to tweak the threshold-time.