Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sanitize user input in laravel

Tags:

php

xss

laravel

I've got a simple question: When is it best to sanitize user input? And which one of these is considered the best practice:

  1. Sanitize data before writing to database.
  2. Save raw data and sanitize it in the view.

For example use HTML::entities() and save result to database. Or by using HTML methods in the views because in this case laravel by default uses HTML::entities(). Or maybe by using the both.

EDIT: I found interesting example http://forums.laravel.com/viewtopic.php?id=1789. Are there other ways to solve this?

like image 602
warmspringwinds Avatar asked Oct 10 '12 06:10

warmspringwinds


2 Answers

I have a full article on input filtering in Laravel, you might find it useful http://usman.it/xss-filter-laravel/, here is the excerpt from this article:

You can do a global XSS clean yourself, if you don’t have a library to write common methods you may need frequently then I ask you to create a new library Common in application/library. Put this two methods in your Common library:

/*
 * Method to strip tags globally.
 */
public static function global_xss_clean()
{
    // Recursive cleaning for array [] inputs, not just strings.
    $sanitized = static::array_strip_tags(Input::get());
    Input::merge($sanitized);
}

public static function array_strip_tags($array)
{
    $result = array();

    foreach ($array as $key => $value) {
        // Don't allow tags on key either, maybe useful for dynamic forms.
        $key = strip_tags($key);

        // If the value is an array, we will just recurse back into the
        // function to keep stripping the tags out of the array,
        // otherwise we will set the stripped value.
        if (is_array($value)) {
            $result[$key] = static::array_strip_tags($value);
        } else {
            // I am using strip_tags(), you may use htmlentities(),
            // also I am doing trim() here, you may remove it, if you wish.
            $result[$key] = trim(strip_tags($value));
        }
    }

    return $result;
}

Then put this code in the beginning of your before filter (in application/routes.php):

//Our own method to defend XSS attacks globally.
Common::global_xss_clean();
like image 199
Muhammad Usman Avatar answered Sep 30 '22 05:09

Muhammad Usman


I would say you need both locations but for different reasons. When data comes in you should validate the data according to the domain, and reject requests that do not comply. As an example, there is no point in allowing a tag (or text for that matter) if you expect a number. For a parameter representing.a year, you may even want to check that it is within some range. Sanitization kicks in for free text fields. You can still do simple validation for unexpected characters like 0-bytes. IMHO it's best to store raw through safe sql (parameterized queries) and then correctly encode for output. There are two reasons. The first is that if your sanitizer has a bug, what do you do with all the data in your database? Resanitizing can have unwanted consequences. Secondly you want to do contextual escaping, for whichever output you are using (JSON, HTML, HTML attributes etc.)

like image 33
Erlend Avatar answered Sep 30 '22 06:09

Erlend