Sanitize Form Request Data Before Validation In Laravel

Hello artisan in this example i will discuss about laravel sanitize input data. That mean how we can sanitize our input data before saving to the data into database. It is the best practice to secure you laravel application. So to protect sql injection we need to sanitize our input data before form saving request.

In this example i will show you step by step that how to manipulate request data before performing validation in Laravel application to protect from hackers. So this laravel sanitizer example i don't use any package, we will do this using own code to protect sql injection.

It is very important to know how to protect laravel website from hackers and how we can secure our laravel application more. Hope you will enjoy this tutorial. Look, when using form request classes, it can be really handy to be able to manipulate the request data before running any of the validation rules. This could be to:

  • Coerce the data into a format the validation is expecting (e.g. convert a list of comma separated values to an array).
  • Cast a value to another type (e.g. string to integer or string to boolean)
  • Account for common user errors, like typos.
  • Remove inappropriate or potentially malicious content from input data.

 

Let's start with an example of form request for storing a post:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|max:200',
            'body' => 'required',
            'tags' => 'required|array|max:10',
            'is_published' => 'required|boolean',
            'author_name' => 'required',
        ];
    }
}

 

Now let's assume that a user has submitted a form to create a blog post and has passed the following input data to store it into database. 

[
    'title' => 'My bolg post',
    'body' => 'This is the < script >alert('O MY GOD!')< / script > post body.',
    'tags' => 'laravel,code,updates',
    'is_published' => 'true',
    'author_name' => 'Ben Sampson',
]

 

Look at that, those tags are sent from the front end as a list of comma separated values and the is_published input is interpreted as a string. Both of these will fail validation despite being correct from a content perspective, just in the wrong format.

Additionally, in a dangerous spell of bad luck, it seems like the title contains a typo and the body contains some malicious code.

prepareForValidation

Just take a look on this path Illuminate\Foundation\Http\FormRequest class, which all form requests extend, we can see that it uses a trait called ValidatesWhenResolvedTrait. This trait contains the method that what we are looking for to sanitize our form data and these method doesn't use any default action. 

protected function prepareForValidation()
{
    // no default action
}

 

Now we can use it as like below to sanitize our input data. 

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|max:200',
            'body' => 'required',
            'tags' => 'required|array|max:10',
            'is_published' => 'required|boolean',
            'author_name' => 'required',
        ];
    }

    /**
     * Prepare the data for validation.
     *
     * @return void
     */
    protected function prepareForValidation()
    {
        $this->merge([
            'title' => fix_typos($this->title),
            'body' => filter_malicious_content($this->body),
            'tags' => convert_comma_separated_values_to_array($this->tags),
            'is_published' => (bool) $this->is_published,
        ]);
    }
}

 

Now again check the form data input and compare it with before requested data:

[
    'title' => 'My blog post',                  // ✅ Typo fixed!
    'body' => 'This is the post body.',         // ✅ Malicious content removed!
    'tags' => ['laravel', 'code', 'updates'],   // ✅ Now an array!
    'is_published' => true,                     // ✅ Now a boolean!
    'author_name' => 'Ben Sampson',             // ✅ Still the same
]

 

Hope it can help you.

 

#laravel #laravel-8x #laravel-sanitizer