I'm initiating my first start-up. I can't stand attempting to read captchas when signing up for websites, don't want my users to. I looked for alternatives, and I found the checkbox captcha. How is this done, using JavaScript to load a checkbox, and validate it with the same code as would normally be used to make a sign up form?
Thanks.
I looked at the example linked from the article you posted. At first glance, it seems like this can be easily bypassed.
The checkbox captcha works on the basis that spam-bots don't parse or use JavaScript code embedded in webpages. Because of this, they will not find the captcha checkbox element within the form it is searching, and therefore will not send a post value for the checkbox along with the form, and on the server side, you would reject the form if the checkbox value wasn't sent.
The problem with this is:
The checkbox name is always the same (gasp_checkbox)
A bot could easily be "trained" to detect this javascript on your page and act accordingly
Even if you output a random name and value that must be used for the checkbox, it could still be detected
The outcome of those 3 problems means that this is much easier to break than image captchas or other methods. All a bot has to do when they submit your form is add: gasp_checkbox=on to their HTTP request.
That said, if you implement this for yourself on your own site, it is unlikely that any bots will able to get past it because its use is not widespread.
You could make it more secure by doing the following:
Generate unique name/value pairs for the checkbox on the server side, and output those values in obfuscated javascript to the client
Serve the script away from your form, preferably in an external javascript file that is generated by a script.
Verify that the values sent for the checkbox match a pair that was previously generated, and not used before.
If you do those things, I think you could have an effective checkbox captcha. If someone does catch on to it on your site, it may still be trivial to defeat, even with the above safeguards in place, but it may take a while, and still be effective for you most of the time.
Related
to my surprise, I couldn't find any information on this topic, but then, searching for such things always yields a lot of similar but unrelated things...
Anyway, some notes to avoid misunderstandings:
- The question is about HTML, HTTP, Javascript, and Browser behavior. I'm intentionally not speaking about server-side technology because I think making that part work won't be a problem for me.
- I'm not aiming at security, nor do I want to restrict the user in what he/she does. In fact, I want to improve the UI.
Suppose we have an HTML page with a POST-redirect-GET form. Submitting the form causes server-side validation, followed either by results or validation errors. Now suppose it took a few attempts to get all values valid. The URL stays the same, though I have tried using changing URLs. Now the user looks at the result, then wants to go back to whatever page linked to the form. For a nice user interface, this should take 2 clicks on the back button, one to return from the results page to the form, and a second to return to the page before the form. Instead, however, the user has to click past each failed attempt to enter valid values.
How can I avoid this? Note again that I don't want to "hide" anything from the user, just there is no practical case where invalid form values are useful. I found hints that a "single-page application" suffers from related problems due to NOT filling the history, but that's actually the opposite problem, and my application is not "single-page".
As an alternative to avoiding history entries, I'm also perfectly fine with side-stepping the problem in some way, or even building a good user interface around it. But right now, the button says "back" (in the sense of navigation) but does "undo" (in the sense of changing values) to the form. People expect the back button to go back -- they already have ctrl-z for undo.
The straightforward solution -- though I couldn't find anything like that -- would be an HTTP header that says, "here's an updated version of the same resource you requested before, note how it has the same URL, so don't make it appear twice when back-button-ing".
I think the simplest approach would be to use ajax to process your form submission even if it is a multi-part form.
I would have a combination of client side validation to give quicker feedback to your user, and then handle server side validation errors when you receive your return data from the ajax request.
With this method your browser history should be relatively preserved and not filled with success/failure form submissions.
I personally like this client side bootstrap validator plugin:
https://github.com/1000hz/bootstrap-validator
I also use it to update the interface when I get an error message returned from the server.
I've been freelance working on the development of a web app for a company, and I realised that in any of the textboxes you can just type html tags or lines of javascript, which is obviously very problematic as I don't want the users to be able to do things that mess how it looks or functions. Is there a way of making sure html/javascript can't be written into text boxes?
The best approach is to assume that all data being POSTed, or sent via the URI to the server is malicious, until you check explicitly that it is not (Perl actually has a taint mode to enforce this), and validate the data received is valid for the data type you're expecting. You shouldn't rely on validation (only) on the client, as a malicious user may craft special requests without actually using your front end.
Despite the fact that I dont have a lot of info for the problem I will give a try, so be nice to me!! (please provide some more info)
Html or Javascript they have some common expressions, you can exclude those from the textfields by writing a custom javascript validator.
You should validate any user input (textboxes, etc.). This means in example that if you are asking for a number, then you check that the user input is a number, and reject anything else.
You can't (and you should not) "forbid to write HTML/JavaScript", you must "check that the input is valid against what you are expecting".
You should validate the input as soon as you want to use it. If you have some sort of input, keypress, keyup or similar event handler, you should validate the data before using it.
Also you should not inject user data as HTML. In example, don't use element.innerHTML = data; but instead use element.textContent = data; so the data are not parsed as HTML but just injected as text. (if you are using jQuery, use $(...).text(data) instead of $(...).html(data).
I am going to be processing a lot of form data from the client using Ajax. Right now, my way of validating input is to add a 'validate' class to each form control that needs to be checked. When the user enters information (or submits the form) the script looks at the input of each control with that class and verifies its contents before moving to the next tab (or sending it to the server). The issue, of course, is that a user can easily remove the class and the item wouldn't be looked at.
While I will of course be validating the input on the server-side (client data can never be trusted!), a lot of the user-side content generation [new inputs, dynamic forms, removing/adding validate classes, etc.] depends on people not tinkering with the classes. While I know that the client can ultimately do whatever they want, what are some ways to make this process difficult for the client to manipulate?
So far I have thought about:
Running a script at the beginning of the page load that grabs all the HTML inputs with the 'validate' class and stores them in a variable. When the user submits the data or moves to the next tab, instead of looking at the elements with the class 'validate', I instead look to validate the data compared to the contents of the variable.
Adding data-validate HTML attributes to each input and doing the same thing as above (running a script and grabbing the inputs that need validation before the client has time to tinker with the settings)
Is there anything else that can be done? I am a little hesitant to use the above approaches because there may be new, dynamically generated form elements that need to be added/removed to the list; and this + grabbing the data at the beginning of the page load could cause a little unnecessary overhead.
"While I know that the client can ultimately do whatever they want..."
You just answered your question. If that's your starting point, why are you trying to make it harder? Is it worth my while to actually try to hack your site? If it is, I don't care that it's harder. Also, how hard can it be? Are you going to make it so hard to figure out the JavaScript that the next developer who looks at this code also won't be able to figure out what's going on?
Also, you're adding more code. Have you ever written code without bugs? I haven't. So, guaranteed, there are going to be bugs in this thing. So, in the off chance that 1 in a million users might try doing something bad, you'll end up stopping lots of legitimate users who get errors when they're using the site like they should.
Client side checking is ONLY meant to be nice to the end user, to give them immediate feedback. Period.
Might not be the answer you like, but it is the answer. :)
Edit: One last comment. Let's say you did make it REALLY hard. Would you then not do server side checking? Would you say to your boss, "Oh, we made it pretty hard to hack on the client side. They still can. We just made it hard. So no need to do server side checks." Of course not. So, if you're doing server side checks no matter what, you don't gain anything from trying to obfuscate on the client side.
This seems like a silly question, but recently I've been more and more in need of a quite common feature, that I can't find anywhere: I need to do some manipulation with the form data before sending it, but I don't want to show this to the user - I don't want to set the text of the field on the screen, but rather access the place where the values are stored and change one of them right before submit. Normally I'd leave the text field without name, and create a hidden field that would be sent. Upon submit, I copy the text of the nameless field, using it's id, parse it, and then set that to the hidden field, that is finally post. But that seems quite a bit of effort to do something so simple. There are plenty of reasons why one would do such a thing: remove masks, encrypt a password, change a date from local native format to database... All this things can be done server side, of course, but most of them would be way better client side: you'd need to send less data over network, it'd greatly simplify posterior server-side validation... Anyway, is there a simpler way to do it?
Trying to create a very piece of validation to prevent spammers. I want a field with a label saying 'What's 2 + 7?' so the Javascript needs to know the result and pass the validation. I'm struggling to write this, would it be something along the lines of:
var valid = '';
var required = ' is required';
var sum = $('form #sum').val();
if (sum == '9') {
valid += '<p>An answer is' + required + '</p>';
}
It is hard to tell exactly what's needed without looking at more code.
A simple question like this may very well work if it is generated server side and it is a lot better for accessibility than captchas. In order to be effective the question and answer should also be randomly selected.
You may chose to include a pre-submit client side validation for usability purposes, but since spam bots ignore JavaScript, it is useless to prevent them, unless you do something really complicated.
A bonus tip off topic: Your JQuery selector is inefficient. When using an id-selector you will never need to include its parent.
Client side validation via Javascript is not going to do much to guard against spammers. Most spammers will have bots that don't even parse Javascript.
The only way to do this reliably is to handle it server side.
I would recommend trying something like Recaptcha: http://www.google.com/recaptcha
Ok so this is not going to answer your question per se but I want to suggest that you don't do this. Creating these spam preventions mechanisms is actually very complicated and your idea isn't really going to work if a spammer really wants to come after your site. I would suggest you look into a service called recaptcha. It is free, easy to set up and the information entered by users is put to use digitizing old books.
As I wrote in comments, you could prevent the bots from posting your data with just a javascript by itself. Let me explain how you could do it:
You could set initially the wrong or empty action for your form and later, with the help of javascript, set it to the correct one if the answer on the 'sum' was correct. Or even without the request for 'sum' as most of the spam-bots do not run js.
You could insert a hidden field named 'passed' with false initial
value of it. Again, based on form interaction, you could set it to
true and later check the data from the form (the value of this
hidden field) on the server.
The last method, which I prefer in most cases, is to encode html
code of your form with, for example, base64 and use your javascript
to convert it back to HTML code. As soon as bots do not run js, they
will not even know that you have a form on the page. The good part here is that you do not have to ask a person to enter something else in the form.
All these methods can be bypassed by a person interested in spamming on your website. He could check the final data sent to the server and create the set of the same requests to your server. That is why you need some server-side support in order to prevent you form even from manually crafted spam requests.