Preventing bot form submission - javascript

I'm trying to figure out a good way to prevent bots from submitting my form, while keeping the process simple. I've read several great ideas, but I thought about adding a confirm option when the form is submitted. The user clicks submit and a Javascript confirm prompt pops up which requires user interaction.
Would this prevent bots or could a bot figure this out too easy? Below is the code and JSFIddle to demonstrate my idea:
JSFIDDLE
$('button').click(function () {
if(Confirm()) {
alert('Form submitted');
/* perform a $.post() to php */
}
else {
alert('Form not submitted');
}
});
function Confirm() {
var _question = confirm('Are you sure about this?');
var _response = (_question) ? true : false;
return _response;
}

This is one problem that a lot of people have encountered. As user166390 points out in the comments, the bot can just submit information directly to the server, bypassing the javascript (see simple utilities like cURL and Postman). Many bots are capable of consuming and interacting with the javascript now. Hari krishnan points out the use of captcha, the most prevalent and successful of which (to my knowledge) is reCaptcha. But captchas have their problems and are discouraged by the World-Wide Web compendium, mostly for reasons of ineffectiveness and inaccessibility.
And lest we forget, an attacker can always deploy human intelligence to defeat a captcha. There are stories of attackers paying for people to crack captchas for spamming purposes without the workers realizing they're participating in illegal activities. Amazon offers a service called Mechanical Turk that tackles things like this. Amazon would strenuously object if you were to use their service for malicious purposes, and it has the downside of costing money and creating a paper trail. However, there are more erhm providers out there who would harbor no such objections.
So what can you do?
My favorite mechanism is a hidden checkbox. Make it have a label like 'Do you agree to the terms and conditions of using our services?' perhaps even with a link to some serious looking terms. But you default it to unchecked and hide it through css: position it off page, put it in a container with a zero height or zero width, position a div over top of it with a higher z-index. Roll your own mechanism here and be creative.
The secret is that no human will see the checkbox, but most bots fill forms by inspecting the page and manipulating it directly, not through actual vision. Therefore, any form that comes in with that checkbox value set allows you to know it wasn't filled by a human. This technique is called a bot trap. The rule of thumb for the type of auto-form filling bots is that if a human has to intercede to overcome an individual site, then they've lost all the money (in the form of their time) they would have made by spreading their spam advertisements.
(The previous rule of thumb assumes you're protecting a forum or comment form. If actual money or personal information is on the line, then you need more security than just one heuristic. This is still security through obscurity, it just turns out that obscurity is enough to protect you from casual, scripted attacks. Don't deceive yourself into thinking this secures your website against all attacks.)
The other half of the secret is keeping it. Do not alter the response in any way if the box is checked. Show the same confirmation, thank you, or whatever message or page afterwards. That will prevent the bot from knowing it has been rejected.
I am also a fan of the timing method. You have to implement it entirely on the server side. Track the time the page was served in a persistent way (essentially the session) and compare it against the time the form submission comes in. This prevents forgery or even letting the bot know it's being timed - if you make the served time a part of the form or javascript, then you've let them know you're on to them, inviting a more sophisticated approach.
Again though, just silently discard the request while serving the same thank you page (or introduce a delay in responding to the spam form, if you want to be vindictive - this may not keep them from overwhelming your server and it may even let them overwhelm you faster, by keeping more connections open longer. At that point, you need a hardware solution, a firewall on a load balancer setup).
There are a lot of resources out there about delaying server responses to slow down attackers, frequently in the form of brute-force password attempts. This IT Security question looks like a good starting point.
Update regarding Captcha's
I had been thinking about updating this question for a while regarding the topic of computer vision and form submission. An article surfaced recently that pointed me to this blog post by Steve Hickson, a computer vision enthusiast. Snapchat (apparently some social media platform? I've never used it, feeling older every day...) launched a new captcha-like system where you have to identify pictures (cartoons, really) which contain a ghost. Steve proved that this doesn't verify squat about the submitter, because in typical fashion, computers are better and faster at identifying this simple type of image.
It's not hard to imagine extending a similar approach to other Captcha types. I did a search and found these links interesting as well:
Is reCaptcha broken?
Practical, non-image based Captchas
If we know CAPTCHA can be beat, why are we still using them?
Is there a true alternative to using CAPTCHA images?
How a trio of Hackers brought Google's reCaptcha to its knees - extra interesting because it is about the audio Captchas.
Oh, and we'd hardly be complete without an obligatory XKCD comic.

Today I successfully stopped a continuous spamming of my form. This method might not always work of course, but it was simple and worked well for this particular case.
I did the following:
I set the action property of the form to mustusejavascript.asp which just shows a message that the submission did not work and that the visitor must have javascript enabled.
I set the form's onsubmit property to a javascript function that sets the action property of the form to the real receiving page, like receivemessage.asp
The bot in question apparently does not handle javascript so I no longer see any spam from it. And for a human (who has javascript turned on) it works without any inconvenience or extra interaction at all. If the visitor has javascript turned off, he will get a clear message about that if he makes a submission.

Your code would not prevent bot submission but its not because of how your code is. The typical bot out there will more likely do an external/automated POST request to the URL (action attribute). The typical bots aren't rendering HTML, CSS, or JavaScript. They are reading the HTML and acting upon them, so any client logic will not be executed. For example, CURLing a URL will get the markup without loading or evaluating any JavaScript. One could create a simple script that looks for <form> and then does a CURL POST to that URL with the matching keys.
With that in mind, a server-side solution to prevent bot submission is necessary. Captcha + CSRF should be suffice. (http://en.wikipedia.org/wiki/Cross-site_request_forgery)

No Realy are you still thinking that Captcha or ReCap are Safe ?
Bots nowDays are smart and can easly recognise Letters on images Using OCR Tools (Search for it to understand)
I say the best way to protect your self from auto Form submitting is adding a hidden hash generated (and stored on the Session on your server of the current Client) every time you display the form for submitting !
That's all when the Bot or any Zombie submit the form you check if it the given hash equals the session stored Hash ;)
for more info Read about CSRF !

You could simply add captcha to your form. Since captchas will be different and also in images, bots cannot decode that. This is one of the most widely used security for all wesites...

you can not achieve your goal with javascript. because a client can parse your javascript and bypass your methods. You have to do validation on server side via captchas. the main idea is that you store a secret on the server side and validate the form submitted from the client with the secret on the server side.

You could measure the registration time offered no need to fill eternity to text boxes!

I ran across a form input validation that prevented programmatic input from registering.
My initial tactic was to grab the element and set it to the Option I wanted. I triggered focus on the input fields and simulated clicks to each element to get the drop downs to show up and then set the value firing the events for changing values. but when I tried to click save the inputs where not registered as having changed.
;failed automation attempt because window doesnt register changes.
;$iUse = _IEGetObjById($nIE,"InternalUseOnly_id")
;_IEAction($iUse,"focus")
;_IEAction($iUse,"click")
;_IEFormElementOptionSelect($iUse,1,1,"byIndex")
;$iEdit = _IEGetObjById($nIE,"canEdit_id")
;_IEAction($iEdit,"focus")
;_IEAction($iEdit,"click")
;_IEFormElementOptionSelect($iEdit,1,1,"byIndex")
;$iTalent = _IEGetObjById($nIE,"TalentReleaseFile_id")
;_IEAction($iTalent,"focus")
;_IEAction($iTalent,"click")
;_IEFormElementOptionSelect($iTalent,2,1,"byIndex")
;Sleep(1000)
;_IEAction(_IETagNameGetCollection($nIE,"button",1),"click")
This caused me to to rethink how input could be entered by directly manipulating the mouse's actions to simulate more selection with mouse type behavior. Needless to say I wont have to manualy upload images 1 by 1 to update product images for companies. used windows number before letters to have my script at end of the directory and when the image upload window pops up I have to use active accessibility to get the syslistview from the window and select the 2nd element which is a picture the 1st element is a folder. or the first element in a findfirstfile return only files call. I use the name to search for the item in a database of items and then access those items and update a few attributes after upload of images,then I move the file from that folder to a another folder so it doesn't get processed again and move onto the next first file in the list and loop until script name is found at the end of the update.
Just sharing how a lowly data entry person saves time, and fights all these evil form validation checks.
Regards.

This is a very short version that hasn't failed since it was implemented on my sites 4 years ago with added variances as needed over time. This can be built up with all the variables and if else statements that you require
function spamChk() {
var ent1 = document.MyForm.Email.value
var str1 = ent1.toLowerCase();
if (str1.includes("noreply")) {
document.MyForm.reset();
}
<input type="text" name="Email" oninput="spamChk()">
I had actually come here today to find out how to redirect particular spam bot IP addresses to H E L L .. just for fun

Great ideas.
I removed re-captcha a while back converted my contactform.html to contactform.asp and added this to the top (Obviously with some code in between to full-fill a few functions like sendmail, verify form filled out completely etc.).
<%
if Request.Form("Text") = 8 then
dothis
else
send them to google.com
end if
%>
On the form i stuck a basic text field with the name text so its just looks like anything not specifying what its for at all, I then stuck some text 2 lines above in red that states enter what 2 + 6 = in the box below to submit your request.

Related

How do I load reCAPTCHA Score and Checkbox on the same page?

Currently on a login page, I need to have both the score and checkbox reCaptcha evaluation on the same page, if the score fails I need to dynamically load the checkbox score.
Currently I have it working although I don't know if I implemented it correctly.
In my HTML header I have
<script src="https://www.google.com/recaptcha/enterprise.js?render=${Login.reCaptchaScoreKey}"></script>
and in the html body I have
<script src="https://www.google.com/recaptcha/enterprise.js?render=explicit"></script>
In AJAX to load the checkbox I have:
var captchaContainer = grecaptcha.render('captcha_container', {
'sitekey' : siteKey,
'callback' : function() {
$("#LOGIN").prop('disabled', false);
}
});
and to submit the score I have the following (I'm attaching the reCaptcha generated token to an HTML element since it was the only way I could figure out to send it to my backend):
grecaptcha.enterprise.ready(function() {
grecaptcha.enterprise.execute(scoreKey, {action: action}).then(function(token) {
$('#g-recaptcha-response').val(token);
submitForm();
});
});
It seems strange that I need to include the reCaptcha JS file twice for this to work which is a bit of a code smell. If I remove the first JS file as expected my score reCaptcha breaks, if I remove the second my checkbox breaks.
Is there a way to do what I want to do by including the reCaptcha JS only once? Or is the way that I'm doing it okay?
I received an official response for the reCAPTCHA Enterprise support team:
Thanks for reaching out here. We recommend not putting a checkbox
behind a score. More details are available on this here:
https://cloud.google.com/recaptcha-enterprise/docs/faq#id_like_to_use_the_score_from_to_show_a_challenge_checkbox_widget_how_can_i_do_this
Not only are there concerns listed in that FAQ point about the
efficacy of a checkbox widget when placed behind a score, but it also
over simplifies how the checkbox widget works. We perform "adversarial
challenging" on our checkbox widget (essentially, we show harder
challenges to known attackers), but we're unable to do so when placed
behind a score reCAPTCHA.
All of this being said, if you do wish to do it anyway, you would
have to include the JS file twice.
And this is from the link posted in their email:
I'd like to use the score from reCAPTCHA Enterprise to show a challenge / checkbox widget. How can I do this?
We recommend that you do not do this. reCAPTCHA Enterprise expects to
see both good and bad user behavior on implementation. If you trigger
a reCAPTCHA Enterprise checkbox widget based on a reCAPTCHA Enterprise
score, the checkbox widget is only being exposed to bad traffic. Due
to this, the widget can have a more difficult time determining whether
to show a challenge or not. This can result in issuing NO CAPTCHAs (no
challenge shown at all) to fraudulent users or bots due to trouble
making that differentiation.
In these cases, we recommend just using a challenge-based site key
upfront (like reCAPTCHA Enterprise with a CHECKBOX Site Key) instead,
but installing a SCORE Site Key on every page, as well as issuing
grecaptcha.enterprise.execute to train the model, but foregoing
assessments on the SCORE tokens. Essentially, this achieves the goal
by training the reCAPTCHA Enterprise CHECKBOX site keys on user
behavior, resulting in less challenges shown to legitimate users and
more challenges to fraudulent ones.
Adding to your own answer, check https://developers.google.com/recaptcha/docs/faq#can-i-run-recaptcha-v2-and-v3-on-the-same-page for more detail of you still want to do it.

How do I verify the user with AJAX after user logined?

I'm totally new to make a website with javascript AJAX. I want to provide every experience on my website with one domain(like Facebook), thus I made every page-changing method with javascript AJAX. At first, when you visit my website, you have to log in, after that it turns to the main page and you can go to several menus with clicking button which triggers page-changing method.
The problem what I faced is.. I've recently seen someone typed javascript code into the console to delete all of his(or her) photos on Tumblr instead of clicking all of that. The idea hit my head.
Every page-changing method in my website also can be called without login. Someone can input page-changing javascript code in the console without login and see the contents of pages.
The first idea came to my head to prevent this situation was, to send id/pw every time when I make a post request to the server and everytime server gets the request, server checks the id/pw to assign the browser to change page. For instance, when a user wants to go to menu A, he(or she) has to send his(or her) id/pw to see the content of menu A.
I thought this is such a bad idea. As I guess it will result overload in server CPU when the server always has to check id and pw(sorry, I don't know well about server CPU and process, this is just my supposition). So I guess there is another way to verify the user and their requests without sending id/pw every time.
Does anyone know about that? Or should I check id/pw with every post requests?
To answer you, you are talking about Cross Site Scripting. Let me first point you to some documents in order to make you aware of what you are dealing with:-
Its called Cross Site Scripting using which a user on the client side inject script in your website and change the different stuff on it.
https://en.wikipedia.org/wiki/Cross-site_scripting
Now to deal with such things there are remedies as following:-
CSRF Token
JWT
Both of them work in somewhat identical way but there are data and payload carrying capacity and encryption involved in JWT and I recommend that.
This is a very known problem in the community and is also pretty old.
On the other hand I will also recommend you to do a data sanitization before storing it into your database. Someone can easily input some JS in your site and you can be defaced in no time.
Have a look at this Sanitizing user input before adding it to the DOM in Javascript
Last but not the least. Stop exposing the functions in the Global level while writing JavaScript. Stop creating global variables and functions and rather use closures.
(function(){
var a =10;
var b = 20;
function add(msg){
console.log(msg)
return a+b;
}
add("I am calling from Inside the self executing function");
})();
add("I am calling from outside the self executing function");
Have a look at the code above and how it protects that add() method to be called from outside.
Hope this answers your questions.
Yes, on stateless scenarios you should send some client identification like a token and verify on the server. Don't worry about the performance :)
You could take a look to JWT: https://jwt.io/

PHP Double-Click Dilemma

We have a problem with users double-clicking on buttons within our application to proceed from screen to screen.
We have implemented the ( onclick="this.disabled=true" ) on our buttons but we are convinced that it is not always sufficient to stop the fast-fingered double-click.
A simple example :-
Screen A has four input fields and a proceed button. When the proceed button is pressed, control is passed to server-side routine to validate info, set some session vars and call screen B.
What appears to happen occasionally is :-
On first click the server-side routine is called and begins validating info and setting session vars. Second-click takes control and again calls the server-side routine and begins validating info and setting session vars -> for us, the session vars are already set and this highlights the problem.
We have looked at tokens but don't think they will solve our problem.
We think that since every PHP application must be vulnerable to this double-click issue there has to be a standard method for resolving it but we have yet to find one.
If you have resolved this issue then we would be grateful if you would like to give us some insights into how we might overcome the problem.
* Thanks for the replies. Loic and Brian Nickel - hard to separate as both going for the token method via timestamp or GUID. We will have to go back and take another look at tokens. After discussion - as a preferred solution for us, we would go with the GUID token concept.
Since double click will basically submit the same form twice you can check the timestamp between two submits.
I'll take the example of stackoverflow because this site is awesome.
Let's say I vote this question up, server side, if my POST request is valid, then my POST request will be treated, and saved.
Then server side, before treating a request, they will check if this same form hasn't been posted in last few seconds (don't they?).
Anyway, my point is, give your forms a name, and when validated, put a timestamp in your users session so you can refuse their post of the same form given a defined amount of time.
Best of luck.
This is a very common problem with a fairly standard solution. Whenever you generate your form, you should generate a unique token like a GUID and stick it in SQL, redis, memcached, the session, or any short term persistent store you have. Stick it in a hidden field. You should be doing one token for each generated form.
When the form gets submitted, atomically check for and remove the token from the store. If it's there the form was submitted for the first time. If not, it's a duplicate.
For bonus points, instead of showing an error on the second submission, you can store the token with the successful result data and use it to render the same success page as you would have if they clicked once.
1) Put a for the eye hidden div (or other element) on z-top of button (opacity:0.01)
2) when once clicked (mousedown) remove div
or:
1) Remove click event when once clicked

Remove server side validation and make a full blown client side validation?

Is it recommended to make all the necessary input validations in client side? I want to optimize the processing of the server (meaning lesser double validation so that the programmer may focus only to business logic).
Example:
On the client side, there's an 'Age' input textfield (JavaScript will not allow to submit the form unless it's within the range)
On the server side, there's no more validation of the 'Age'
// instead of validating again the age
int age = Integer.parseInt(request.getParameter("age"));
// check age if valid
if(age >= 0 ) { /* codes * / }
We can instead proceed only to
int age = Integer.parseInt(request.getParameter("age"));
because we are very sure that it is valid.
To accommodate disabled JavaScripts in Web browsers, we need to check first. If JavaScript is enabled, proceed to the application, otherwise block the application. (Just like Facebook)
Is my theory / concept acceptable?
If you need to enforce certain input patterns, you cannot rely on data that comes from the client. Folks can disable JavaScript, or simply bypass your validation completely and send whatever data they want. However, most casual users will not have this problem, and the data is coming from the client anyway.
In short, it depends.
For most of my applications, I have client-side validation and only worry about some things server-side that can throw an error condition. For example, if I have a form that sends an e-mail to someone, I will have JavaScript that checks for a valid to: e-mail address, and alert the user. Server-side, if that e-mail address isn't valid or isn't present, I will simply throw an error writing code to let the user nicely know something has gone wrong. For the message body, I'll validate client-side whether or not it has one, but server side I won't really care. Again, what you do depends on your needs.
I believe in validation EVERYWHERE
I like to have client side validation for:
required fields populated
minimum size fields (like zip)
Regex for proper character types in proper locations (eg social security numbers, new passwords, etc)
privilege enforcement (users can only see and do what their role should be allowed to)
Server Side validation for:
all client side requirements
entity associations (child-parent relationships are legit)
changes or requests are Role-Authorized
User Entry is the enemy! Users will find a way to break your site willingly or un-willingly. Things will fall through the cracks. So I strongly endorse double and triple checking.
I would believe in client side validation to save server processing, if it NOT for my fear that this kind of thinking will make me exceptions more prominent.
Overall, the reasons why I value rich Client side validation are:
one more level of checking data integrity (as well as server side)
guiding users; intelligent client side validation makes helps users make more efficient answers quicker
a better experience; If users don't have to wait for the loop back to server and returned to client to see their errors, their user experience should be better.
If security / data integrity is a concern, I would advise against this. While it'll be enough to prevent Joe Smith from entering unwanted data, you'll leave your system open to serious data manipulation from people who understand how the web works.
Let's say you have a voting system like on StackOverflow where anytime a user votes, an AJAX call is made. While the JS validation may prevent a person from using the displayed HTML to cast multiple votes on the same question or answer, it will not prevent a user from going into their browser's console and manually submitting POST or GET requests to get around the JS validation. Before you know it, you'll see Lloyd Banks with 100k reputation after answering just a few questions

Spam-prevention for my contact form

I've been doing a lot of research about spam-prevention methods, I do not want to resort to using CAPTCHA.
The form typically sends an email to the user and the webmaster with the contents of the form.
The first thing I've done is to remove the contents of the form in the email sent to the user and simply have a confirmation message.
I have added a row for the persons 'title' and hidden the row using CSS, if the field is filled in. The submission completes without sending any emails.
I'd like to add a couple of other techniques,
Check the time to complete submission - do not send emails if under 5 seconds.
Pass through an unique ID - do not send emails if no match
The problem is that website pages are cached, so directly setting a session variable is useless. I'm considering use ajax to hit a CFC and set the variable, but it would require JavaScript.
Should I restrict submissions to only those with JavaScript enabled? Or are there any alternative suggestions?
Thanks
Daniel,
I have a similar spam-detection approach that has been in place since last year. I can share what I have seen.
Session based tests:
Checking the time it takes someone to fill out the form and checking that the user comes from the right page have been very reliable checks, though somewhat fraught with difficulty. In your case, forcing users to have modern, javascript enabled browsers might be your best option. And it seems like it's becoming a more accepted practice, I guess, right? I don't really know..
Content based tests:
Another two fairly helpful practices are to check that form fields contain different values and that no more than a specified number of URLs have been entered. Spammers almost always seem to stick the same trash URL into every field. However, these checks aren't nearly as good as session-based checks.
Our spam-detection heuristic has a few other checks, in addition to the ones above:
Basic regex injection tests - bare-bones, but I can share if you are interested
Spam Content - pretty useless - a simple library constructed mostly by hand
Banned IP Address - also pretty useless..
Some numbers from our heuristic over the last year or so.
Total failed tests= 83,356
Failed Injection Test = 54 (0 failed this test and no other tests)
Failed Too Many URLs In Input Test = 18,935 (2396)
Failed Spam Content Test = 3673 (46)
Failed Hidden Field Tampering Test = 60,295 (1479)
Failed Dubious Time Elapse Test = 64,430 (17,126)
Failed Invalid Session Test = 28,706 (140)
Failed Fields Contain Same Values Test = 167 (49)
Failed Banned IP Address (not implemented) = 0 (0)
I don't want to post too many details about exactly what our criteria are, but if you are interested I'd be happy to share code.
-Ben
I suggest you take a look at http://cfformprotect.riaforge.org/ as it works well for me.

Categories