Background:
I've been searching for a way to sanitise some form inputs with JavaScript to prevent the form being submitted if it contains characters that aren't whitelisted.
I've come up with this based off a brilliant Stack Overflow answer
function allowSubmission(string) {
return string == string.replace(/[^\w\s]/gi, 'X');
}
var s1 = 'simple string';
var s2 = 'alert(0);';
var s3 = '<nasty>string';
console.log(allowSubmission(s1)); //true
console.log(allowSubmission(s2)); //false
console.log(allowSubmission(s3)); //false
Problem
But doesn't this just mean a potential attacker can turn off JavaScript and submit whatever the hell they like? Or simply edit the JavaScript on the fly and overwrite the validation method to just return true.
Question
SO... Isn't input sanitisation with JavaScript pointless?
This only means you should always validate and sanitize your input server-side. Regardless of whether it's checked in front-end as well.
Doing this in JavaScript can help you avoid unnecessary requests hitting your backend and increasing the load as well as improve the user experience but they should not be treated as a means of security.
It's pointless, when treated like a line of defence. In general, its use serves many purposes.
But doesn't this just mean a potential attacker can turn off javascript and submit whatever the hell they like? Or simply edit the javascript on the fly and overwrite the validation method to just return true.
Yep, but that doesn't make javascript validation pointless.
The purpose of javascript validation is not to sanitize input for the server. That job must be handled by the server.
The purpose of javascript validation is to make the user interface more responsive for the user. JavaScript validation allows the user to know when they made a mistake without having to wait for a potentially slow server response. It can also reduce the overall load on the server.
Client-side JavaScript should never be used as the only means of sanitizing input, it can be used to assist the server, but in the end the server must be able to correctly handle invalid input.
Input sanitization is not done for security, but for usability. You should give feedback to the user that he inputs bad characters as soon as possible (on each keystroke), not after he submits the form and the response comes back from the server.
For security you MUST validate anything coming from the client on the server. There is no way around it.
Related
Does anyone have any information on the industry-standard or best practice for checking matching passwords (e.g. Gmail's "passwords do not match" feedback")? Is it a back-end, front-end or client-side process? Or is it completely based on other factors?
Here is an example of the code that I am using (Python with Bottle) to sign up a user. The code works, but I am unsure whether I should provide a flash message from the back-end (where it returns "Passwords do not match") or would it be better to use something like JS? I know that there are scripts out there to validate this, but they are all JS. My question is not how to do it with JS, but which is the preferred method.
#route('/suser', method='POST')
def sign_suser():
cemail = request.forms.get('semail')
cpassword1 = request.forms.get('spass1')
cpassword2 = request.forms.get('spass2')
ctype = request.forms.get('stype')
if cpassword1 != cpassword2:
return "<p>Passwords do not match</p>"
else:
pwhash = crypt(cpassword1)
connection = sqlite3.connect("whatever.db")
cursor_v = connection.cursor()
cursor_v.execute("insert into users (cemail, cpassword, atype) values (?,?,?)", (cemail,pwhash,ctype))
connection.commit()
cursor_v.close()
info = {'status': 'User Added',
'type': 'success'}
return template('whatever',info)
Checking if two password fields match during a sign up should be purely done with client-side logic. It is provided as a safety against a user mistakenly inserting a typo into their password. A server-side check is pointless, as your client will have prevented it and if your user is a tech savvy individual that does everything with curl then it's on them if they mess up.
Also I will expand on your question about best practices. You should not immediately save the user in your database without them first verifying via a link, usually sent to their email, that it is valid. Remember: never trust anything provided by the user.
You need to distinguish between two cases:
You are not able to validate the value without using a database or any non-sharable technique in the back-end. In this case, you're only possibility is to check it in the back-end (with e.g. an Ajax call or a communication over WebSockets). Examples for this kind of validation are: username/password validation or anything which needs a connection to a database, a proprietary algorithm to check a value with a logic which cannot be published
You can validate the value without checking it first in the back-end (database). In this case, you can move the check for performance reasons to the front-end/client side. You still have to protect the back-end against incorrect values (in case of an attack, corrupt JavaScript etc.) Examples for this kind of check are e.g. email address validation, phone number validation etc.
For 1, I would just use a regular connection to the back-end either when submitting the value or while typing (if the response from the back-end is fast enough).
For 2, you have several options:
Do it like in 1. Make a back-end check either while submitting or during the input. This may have some performance issues though (mainly if you are checking it on key down). If you are checking it after submitting, the validation is not real time.
Do it with separate validations on the front-end side and the back-end side. If you are doing. This is not recommended. You are duplicating code between the front-end and the back-end. Avoid it as often as possible.
Do it with shared validation patterns in the front-end and the back-end. This is my recommended way of validating values. This validation works best, if the checks are done with regular expressions (regex). The back-end has a Map() of patterns which are provided over an interface to the front-end. The patterns are loaded initially, when the web applications is loaded and are then present during the runtime of the application. This makes sure, that the validations are always the same on the back-end and front-end side.
Your example however comprises of the matching of two passwords (equality check). This is a special case, because you cannot use a regular expression to check the validity of the value. This precludes the recommended case from above and leaves the two other mentioned solutions.
If your sole purpose is to compare the two values, I would recommend to duplicate the logic. Duplicating is in this case (imho) somewhat justified because the check is very simple and not likely to be changed over time. Making a check to the back-end to soley check for equality is (imho) overstated.
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).
Somehow, when using Prototype's Form.serialize() to submit complex forms, I always feel a bit unsure as to whether this will work in all cases.
Possible issues I worry about are quote/string escaping issues, or perhaps the submission of unusual character codes, anything that could mess up the process.
So the question is:
Is it safe (on the client side) to collect all the data from a form using Prototype and then send it to the server via AJAX or are there any browsers that are known to have troubles sending forms this way — or perhaps, lack of support for it?
While no browser that I know internally uses Javascript to submit a form, the exact details of how a form should be submitted are very well documented.
It is quite possible to write form submission code in Javascript that follows the protocol exactly. On the other hand, an experienced coder may miss some of the edge cases -- like disabled checkbox controls.
I can't speak for the prototype library since I've never used it, but if there is a form that does not submit properly, or a server that does not take a submitted form, then it should be submitted as a bug report.
I'm not sure why you were downvoted originally, it's a valid question.
I think that the real answer, though, is that the security aspect really happens on the backend. It's OK to serialize an entire form and send it through a request but you need to validate the information that you receive on the other side.
For instance, you don't want to do this (or the equivalent in another language):
(assume $form is the serialized form)
foreach ($form as $key => $value) {
$object->$key = $value;
}
save($object);
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.
What is everyone's favorite way to sanitize user data?
I've been using Javascript, but have recently required something more secure (people can turn it off, after all), so I was looking at Flex, but thought I'd ask the community what they thought.
NEVER NEVER NEVER use javascript or any other client-side technology for the only validation. You can use client-side validation to save some load on your server or make your app seem more responsive by showing the error sooner when validation fails, but you should always validate using server-side code.
Personally, I like the ASP.Net validation controls because it gives you the benefit of client-side validation with security of server-side, without having to write your logic twice. Of course, the stock controls are pretty bare, but you can extend them.
Validation should ALWAYS be done server-side. Doing it client-side, in addition, is fine.
How you do it depends on what your app is written in. Any language should be able to handle validation; the logic used is what matters, not the language.
It also depends on what you're doing with the data you're given. Putting it in a URL or storing it in a SQL database requires two very different kinds of sanitization. If at all possible, white-list valid values--don't black-list invalid values. Someone will always be able to come up with a new mal-input you hadn't considered.
Depending on the requirements of your project you may or may not want to implement client-side validation. However, server-side validation should ALWAYS be implemented. I prefer to white-list appropriate inputs and values as opposed to black-listing invalid data because this ensures that no one will ever slip something by that I failed to consider.
always use server side validation at the very least
use regular expressions
PHP Example:
preg_match('/^[\w][\w\,\-\.]*\#[\w]+[\w\-\.]*$/', $_GET['email'], $matches);
if (count($matches) > 0) {
$_GET['email'] = $matches[0];
} else {
die('invalid email address');
}
It's recommended to use both server- and client-side validation.
I use JQuery for client side validation.