Sanitizing Input Using Laravel 5 Form Requests

  • March 31, 2015

Welcome to the incredibly popular Easy Laravel 5 companion blog. To celebrate the new edition's release (updated for Laravel 5.5!) use the discount code easteregg to receive 20% off the book or book/video package! » Buy the book

Laravel 5's form request feature brings sanity to your application forms, both introducing a formalized approach to input validation and removing unwanted logic from your controllers (if you're not familiar with form requests please read this tutorial first). But while much is made of form requests' validation capabilities, there's woefully little information available about how to sanitize form input. I'll hopefully fill this void with a tutorial explaining just how easy it is to do so. Read on to learn how.

The typical form request skeleton class consists of just two methods, authorize() and rules(). The authorize() method can be used to determine whether the requesting user should be granted access to the form request, and the rules() method defines any validation rules which should be used to vet the form input. But what if you wanted to sanitize form data, for instance removing any HTML tags found in the input? The answer is easier than you might think although admittedly the solution isn't particularly obvious. Here's an example demonstrating sanitization of several form fields, followed by an explanation of how it works:

<?php namespace Phpleaks\Http\Requests;

use Phpleaks\Http\Requests\Request;

class LinkCreateFormRequest extends Request {

    public function authorize()
    {
        return true;
    }

    public function rules()
    {

        $this->sanitize();

        return [
          'name' => 'required',
          'url' => 'required|url|unique:links,url',
          'category' => 'required|integer|min:1',
          'description' => 'required|max:300'
        ];
    }

    public function sanitize()
    {
        $input = $this->all();

        if (preg_match("#https?://#", $input['url']) === 0) {
            $input['url'] = 'http://'.$input['url'];
        }

        $input['name'] = filter_var($input['name'], FILTER_SANITIZE_STRING);
        $input['description'] = filter_var($input['description'], 
        FILTER_SANITIZE_STRING);

        $this->replace($input);     
    }

}

As you can see, the rules() method will first execute the sanitize() method before carrying out the validation. The sanitize() method is where the data filtering logic is found. It filters the name, url, and description fields in various fashions, beginning by retrieving all of the form input values using the $this->all() method. This associative array contains the four submitted form values (name, url, category, and description). The url value is cleaned up by ensuring http:// is prefixed to the URL should http:// or https:// not be included.

The name and description values are filtered using PHP's filter_var() function. Specifically, the FILTER_SANITIZE_STRING option is used to remove all special characters from the strings.

Once these tasks are complete, you can replace the provided form input with the filtered version using the $this->replace() method.

Using this approach, the sky is the limit in terms of how you can filter user input while still taking advantage of Laravel form requests!