Why your website needs validation

Contents

  1. Intro
  2. Forms
  3. Custom Validation
  4. Summary

Intro

Continuing on from my previous blog about 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

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.

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. [email protected]" />
    </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

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

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!

These are webmentions powered by webmention.io