23

An interesting feature of HTML5 is the <input pattern="" /> attribute, which allows the browser to validate the input field's value against a regular expression provided by the developer.

Subsequently, this binds to the field's ValidityState which can then be queried for UX feedback, to prevent invalid submission, and so on.

The server implements the same precondition validation (as well as XSRF).

Given this, is this client-side validation pattern mature and adequate, or is it for some reason still desirable to intercept the entire form and subject it to traditional per-field validation before submitting it?

  • 5
    "...is this client-side validation pattern mature and adequate..." Given that this isn't about security but programming (see answers)...if HTML5 validation has everything you need then yes. Obviously if browsers you have to be compatible with support required features... – Adriano Repetti Sep 19 '17 at 20:16
  • @AdrianoRepetti Indeed, there are obvious concerns from both experiential and development (primarily maintenance) viewpoints. My goal in asking here was to test my underlying reasoning, which is happily congruent with this community. (You've no doubt seen places that will do silly things like prevent paste in a password field "for security reasons". That, like a second round of validation, is provably pointless.) – msanford Sep 19 '17 at 20:26
  • @ms yes, I din't mean question is off-topic but that about security you have already have answers and my 2 cents are for the "mature and adequate" part of HTML5 validation – Adriano Repetti Sep 19 '17 at 20:28
  • 1
    Yes, it's sufficient for user-experience, no it's not sufficient for security experience. – Ryan Sep 19 '17 at 23:49
109

From a security perspective, you need to revalidate everything on the server. This will always be the case, no matter how pretty and advanced HTML5 features become. You simply can not trust the client. You have no idea if it will follow the HTML5 rules or not. You don't even know if it is a browser.

So should you validate the whole form with your own JS client side before submitting it, even if you use the HTML5 features? From a security perspective it doesn't matter. Client side validation have zero security value anyway - see above - so from a security perspective you might just as well not bother doing it at all.

Client side validation is purely about user experience. If your own JS validation or HTML5 built in makes for the best UX is an interesting question, but it is not on topic here.

14

An explanation with code and screenshots

The answers given are great. But I wanted to illustrate this with some code/screenshots.

The bottom line is that anything client side can be manipulated (disabled/completely got rid of/bypassed or modified) by the end-user. So any sort of "client side validation" is totally useless from a security perspective. You must always validate things server side.

Let's say you have a HTML form like this:

<form method="post" action="index.php">
    <input type="email" name="emailAddress" required>
    <button type="submit">Submit form</button>
</form>

This is asking for an email address (type="email"), saying it's a required field (required attribute).

If I try and submit something that's empty or not an email address it'll error, e.g.

enter image description here

Why is this useless from a security perspective? All the user has to do is manipulate the HTML. They can either do this by saving a copy of the web page, editing it, and then reopening it. Or they can use the Developers Tools in their browser to edit the markup. They can do this because it's client side code, and is within their control.

Let's say I change the markup of the form to this:

<form method="post" action="index.php">
    <input type="text" name="emailAddress">
    <button type="submit">Submit form</button>
</form>

I'm now saying the emailAddress field is type text (i.e. not email) and is not a required field (removed required attribute).

So I can submit this to the server. The text string "andy" is obviously not a valid email address. But since we have no server side validation (yet) it'll quite happily be posted to the server and then if the PHP code used $_POST['emailAddress'] it would have "andy" as its data.

enter image description here

I could also submit the form without any data, in which case the application - without any server side validation - would have an empty string in the variable $_POST['emailAddress'].

This was only possible because I as the end-user could manipulate the client side code.

Why is server side validation secure? The end-user cannot manipulate the server side code (unless the server has been compromised, but that's very much a separate issue and not something that's as easy as manipulating HTML for the average person).

So, in PHP, I could do a check like this:

if (!filter_var($_POST['emailAddress'], FILTER_VALIDATE_EMAIL)) {
    die('Invalid email address');
}

Although this is a non-friendly error handling method, it will stop script execution if the user submits "andy" instead of a valid email address. The application will therefore never use "andy" as a variable it was expecting an email address to be in. Since the end user cannot manipulate the PHP code above, there's less chance they can bypass the validation. This is server side validation - it can't be (easily) changed by an end-user because it's not within their control to change it.

Why bother with client side validation at all then? Client side validation is useful for "nice looking" user interface enhancements, or for example error messages/disabling form fields. For example, it's arguably a good UI feature to have that message on the first screenshot in case the user mis-types an email address. The form won't even submit under the first set of conditions, thus reducing un-necessary data being sent to the server. But ultimately, anything done client-side can be changed by the end-user. So it's in no way secure and you should never think of "client side validation" when it comes to security practices. Any client side validation is largely for User Interface enhancements only.

Client side validation is also useful for client side applications (when it's not requesting/posting to a server). For example if you had the form given above and then displayed the contents of emailAddress in a <div> on the page by reading it with JavaScript/jquery. If the user entered something such as <script>alert('hello!');</script> and there was no validation, it would produce an alert when the JavaScript attempted to write the value in the field to the <div>. Nothing is being posted to the server in this case - it all happens client side - so again client side validation is useful in this type of scenario. However the same rationale applies in that a user can still disable the validation. The impact here is lower because if they did run the above code it would only happen on their local machine, not to other users of the application. For example:

enter image description here

Using the following code (without any validation):

<form method="post" action="#">
    <input type="text" name="emailAddress" id="emailAddress" size="100">
    <button type="submit">Submit form</button>
</form>

<div id="test"></div>

And jquery to write the form contents to a <div> with the ID test:

$(document).ready(function() {
    $("button").click(function(e) {
        e.preventDefault();

        $("#test").html($("#emailAddress").val());
    });
});
5

As Anders stated, client-side validation is irrelevant for the security of the application, but very important from the UX point of view.

Client-Side validation is focused o providing the user a smoother and easier time while filling your forms, the best example I know is the jQuery Masks plugin, wich can be used to limit input size and pattern while providing a visual feedback for the user. This may help you on non-security flaws, like receiving data from the users in a different pattern than expected on the server side, but is easily ignored by any attacker.

tl;dr - There's no such thing as sufficient client side validation, simply don't trust the client, just treat everything received on the server before processing it.

1

None of the answers so far really mention it, so let me add this:

The reason why anything in your HTML is completely irrelevant for security is that any attacker can, trivially, create requests without even loading any HTML in the browser (by typing in a request in the console, or using some plugin). Actually, without even starting your browser (c/f curl, wget or any programming language).

The relevant part for these things are the HTTP requests. Not the HTML payload. And except for the TLS/SSL layer, there is nothing safeguarding the HTTP request contents from the person actually creating the request.

So, any and all security has to take place server side. Any client-side checks are just there for a better user experience (skipping a roundtrip).

1

HTML validations will apply only for those who dont know how to change the html code from client side. These html validations can easily be removed and manipulated from client side Always have proper validation on your db.

  • 1
    No reason that validation has to happen in the database. Plenty of reason why it should happen server-side. – a CVn Sep 22 '17 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.