A warning
Not requiring server validation means controlling the user’s browser.
This implies that any solution will be easily circumvented with minimal Javascript knowledge. Another possible attack is simply replicating the HTTP request without actually using a browser. Opera summary: no server validation any solution will be extremely vulnerable.
Solution that does not require server validation
To prevent only more naive attacks, a solution is to use an event on the page that enables the submission of the form if identified that a real user is accessing the page.
The challenge is to identify the pattern of a real user. I imagine a user will either click the button or use the key TAB until we get there, right? Then we could activate the submission only if there is an event mouseover
or focus
on the button.
In addition, to prevent an automatic script from identifying the action
and form fields I would use a solution with Ajax.
See the following example of two fields with one button:
Field 1: <input id="f1"/><br/>
Field 2: <input id="f2"/><br/>
<button type="button">Enviar</button>
And then a script that monitors events mouseover
and blur
, adding the event click
that will make Ajax only when one of the first two events is executed:
//monitora por focus e mouse over
$('button').bind('focus mouseover', function() {
$(this)
//eventos não são mais necessários
.off('mouseover focus')
//adiciona o evento que executará a requisição final
.click(function() {
console.log('implementar ajax aqui');
});
});
Anyway, I believe it is possible to help this also for a submit
conventional if applicable.
Solutions that require server validation
Here I will record the response I had written using server validation.
There are several solutions for not using captcha, some more professional others based on creativity.
Hidden field for "humans"
One response from the OS gave the idea of creating a hidden field in the form. A "robot" program that sends messages automatically will try to fill this field with some random information. Then your code will know that if the hidden field is filled someone has been messing around with something they shouldn’t.
Example:
<!-- este campo não deverá ser preenchido, mas provavelmente os bots tentarão fazê-lo -->
<input type="text" id="nao_humano" name="nome" />
<!-- este campo é o que realmente o usuário deve preencher -->
<input type="text" name="nome_real" />
<!-- o estilo inibe o campo que o usuário não deve preencher -->
<style>
#nao_humano { display: none }
</style>
Service with artificial "intelligence"
Some services do the job of identifying spam. For example, in the my blog I use the Akismet.
Akismet works something like this:
- User submits a comment in the form
- A code on my website receives the message and sends it to the Akismet service
- The Akismet service checks the comment against a spam information base
- Akismet returns saying if the message is a potential spam or not
Obviously, there is some concern about the safety of this process. In a public blog there are no difficulties, but for a company that receives information from clients the traffic of information to a third party server can be a deterrent.
Detecting human behavior
Another idea I’ve seen around for some time is to detect events on the site to validate whether someone is actually typing the message.
Doing this is relatively simple. First, generate a random code and place it in the user’s session. Print that same code into a Javascript block within the page:
var codigo = 'CODIGO_GERADO';
Then add a hidden and initially empty field to the form:
<input type="hidden" name="validacao"/>
Now create a code at some event like mouse over or key up on the page that fills the field validacao
with the value codigo
.
Finally, the server should validate the field validacao
came with the code. To dribble some spammers smarter, the name of this field can also be random.
Completion
In my opinion, creativity is the one who rules this point. The more different and creative your solution, the more difficult spammers will detect it.
Don’t forget that any customer validation can be easily circumvented by any user who knows how to use the developer tool and has an intermediate knowledge of Javascript.
You cannot enter the Hidden field?
– bfavaretto
@bfavaretto can, but the server will not check whether this field has been filled or not.
– Paulo
I even spent time writing an answer, but after reading the restrictions I saw that it was impossible. Orion, even captcha should be validated on the server. There is no way to prevent spam on client, otherwise it would be enough to play the HTTP request without using a browser.
– utluiz
It is very complicated to have nothing on the server... It is possible to make a bot to catch the
action
ofform
, pick up the fieldsinput (text e hidden)
, generate random text and make aGET
. I think if you can’t move the server, why not change the destination of the form to another place you might receive or receive SPAM treatment? And why not a solutionthird-party
? Delegate this responsibility to someone who knows how to treat.– Wakim
@utluiz changed the rules and made some recommendations
– Paulo
@bfavaretto edited the question
– Paulo
@Wakim edited the question
– Paulo
Something with Javascript’s localStorage may be the solution. But it is client dependent. And any modification of the code by the client can end the solution.
– Pedro Henrique
I would suggest adding the tag [tag:usability], because I understand that not using Captchas in the question has to do with the difficulty imposed on users. I have no time to prepare an answer, but here is the best article I have ever read on the subject: http://www.smashingmagazine.com/2011/03/04/in-search-of-the-perfect-captcha/
– Luiz Vieira
Take a look at this question in the EN OS, the first two answers are interesting. First measure the time between the page load and the form’s Ubmit (combined with the construction of the form via javascript, because if the bot does not run javascript, it cannot cause spam). And the second is to create a honeypot, to have a hidden text field that the user doesn’t see, if someone filled it out means that they’re not an ordinary user. Follow the link: http://stackoverflow.com/questions/2387496/how-to-prevent-robots-from-automatically-filling-up-a-form
– Wakim
You can use Akismet ( http://akismet.com/ ) or some trap for robots like Spampoison ( http://spampoison.com ). Spampoison at least once seemed to work, I don’t know if today bots are smarter... Take a test!
– Guilherme Chaguri
Orion, I just "desexcluir" my reply from last week with some more information. I hope it helps!
– utluiz
It doesn’t make much sense not to check on the server, because spam can be sent STRAIGHT to the server, without using any extra functionality of your form! A spam script can read your form only to get the name of the fields, but do the GET or POST directly.
– Bacco
@Bacco the idea is to prevent indirect spam, those performed on random websites. For this purpose the use of Javascript only can solve this problem, for example by setting the address of
action
afterx
seconds or when the user performs some action on the page as aclick
etc..– Paulo
@Bacco the question is how the bot will find the address of
action
ofform
to send messages if the bot has not performed human actions. I think there are several possibilities to prevent a bot from submitting a form, especially when it requires human actions for thisform
appear or work.– Paulo
@Orion from your statement you already take part of the solution ;) I already prefer something that does not depend on JS to work, but you can, as mentioned in the action, change the destination of the action via JS after the form loaded.
– Bacco
@Bacco the main idea is to discover solutions that I can not see, I have some in mind, but I wanted to know others in the view of the guys :), since it is a contact only form, I look for something simple and functional
– Paulo
If you use MVC . NET there is a unique code for this. @Html.Antiforgerytoken()
– Dorathoto