Why your website needs validation
Tags: webdev, javascript, beginners, security
Published: 2021-05-30 21:19:39






## Contents

1.  [Intro](#intro)
2.  [Forms](#forms)
3.  [Custom Validation](#custom)
4.  [Summary](#summary)

## Intro <a name="intro"></a>

Continuing on from my previous blog about [website security week](https://jordanfinners.dev/blogs/website-security-week), we're going to talk about a validation.

If accept user input, you are going to need to validate the input. Non validated user inputs can lead to security vulnerabilities for example SQL injection attacks, where user input escapes your database and starts modifying it. It can also lead to exceptions from your code if a user inputs text rather than a number for example.

Please Please Please ensure you do the same validation server side as you do on the frontend (client) side.

## Forms <a name="forms"></a>

You user inputs should be contained in HTML forms which comes with lots of powerful validation tools built in.
This also means you can start to add validation without adding any extra javascript, increasing performance.

First thing to check on your inputs is, are you using the correct type:

*   button
*   checkbox
*   color
*   date
*   datetime-local
*   email
*   file
*   hidden
*   image
*   month
*   number
*   password
*   radio
*   range
*   reset
*   search
*   submit
*   tel
*   text
*   time
*   url
*   week

This will provide lots of out of the box validation goodness from the outset. [More information on the types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types).

Next up for file inputs ensure you've set the `accept` attribute which allows you to check the type of the file for example `accept="image/png, image/jpeg"`.
You should also set the `multiple` attribute to whether you are allowing many files or a single.

Next up for number inputs set the `step` attribute to ensure only increments of the amount you want are allowed to be entered.
Also set the `min` and `max` values as required to limit the numbers that can be inputted.
For non numeric values there are `minlength` and `maxlength` which limit the number of characters that can be inputted.

Finally we have `pattern` attribute, this can be used to match a specific Regular Expression to validate the input. If you are using one of the existing types above, for example email, you *don't* then need to have your own email regular expression.

Example usage:

    <form name="venue">
        <label>What is the max number of decimal things?
            <input name="capacity" type="number" placeholder="e.g. 32" min="0" max="100" step="0.1" />
        </label>

        <label>Any images of your venue you wish to upload?
            <input name="images" type="file" accept="image/png, image/jpeg" multiple/>
        </label>
        
        <label>How do we contact you?
            <input name="contact" type="email" placeholder="e.g. bob@bob.com" />
        </label>
        
        <label>Enter UUID to test pattern usage?
            <input name="pattern" type="text" pattern="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
        </label>
    </form>

## Custom Validation <a name="custom"></a>

If you want to extend the validation of a form, I would recommend adding an event listener on the form for `submit` event, and then prevent the default action using `event.preventDefault()`.
You can then run any validation on the form using javascript and set `setCustomValidity` on the inputs which then uses the in built goodness of forms and inputs to display the error message.

Example Usage:

HTML

    <form name="venue" onsubmit="submit">
        <p class="passwordRules">Passwords must have at least one uppercase and lowercase letter, one number, and at least 8 or more characters.</p>

        <label>Password
            <input 
            name="password" 
            type="password" 
            required 
            placeholder="XXXXXXXX"
            pattern="(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}"
            title="Must contain at least one uppercase and lowercase letter, one number, and at least 8 or more characters"/>
        </label>

        <label class="secondPass">Confirm Password
            <input
            name="confirmPassword" 
            type="password" 
            required 
            placeholder="XXXXXXXX"
            pattern="(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}"
            title="Must contain at least one uppercase and lowercase letter, one number, and at least 8 or more characters"/>
        </label>
    </form>

Javascript

      /**
       * Handle form submission
       * @param {Event} event the form submission event, preventing the normal form behavior
       */
      async submit(event) {
        event.preventDefault();
        // custom validation of the passwords
        this.validatePassword();
        // grab the form and trigger validation
        const form = this.querySelector('form');
        const valid = form.reportValidity();
        if (valid) {
            // do something with the form
        } else {
          // form isn't valid
        }
      }

      /**
       * Checks to see if passwords match
       */
      validatePassword() {
        const pass = this.querySelector('input[name="password"]');
        const confirmPass = this.querySelector('input[name="confirmPassword"]');
        if (pass.value !== confirmPass.value) {
          confirmPass.setCustomValidity("Passwords don't match");
        } else {
          confirmPass.setCustomValidity('');
        }
      }

## Summary <a name="summary"></a>

In summary, HTML gives us really powerful validation tools to check the user input and validate with minimal Javascript, which we can also extend with a little bit of Javascript too.
We must also ensure that any validation we have completed on the frontend is also done on the server side to prevent users circumventing your frontend and directly interacting with your API.

Validating your user input prevents a whole heap of issues and vulnerabilities for your applications and business.

Happy Validating!