Fijvect's avatar

Elegant way of Input Sanitation?

Hello!

I'm looking for feedback, or recommendations on tweaks, to my current way of input sanitation. I found it odd that Laravel seems to be missing scaffolding for sanitation implementation, and after coding up a few different methods, I've found the solution below to be the easiest, but would like some input or recommendations.

For any model that requires sanitation I've created a SanitizedModel class that extends the base Model class (see below).

So far this works beautifully in all cases but one. I ran into problems when trying to apply it to the built in User models because of php's Single Inheritance limitation, and the User model already extends a different class than the basic "Model" class ("Authenticatable"). How would you recommend I implement this? So far I've had to duplicate code, which I'd obviously rather avoid.

namespace App;

use Illuminate\Database\Eloquent\Model;

/**
 * Model Sanitization wrapper
 */
class SanitizedModel extends Model
{
    /**
     * When set, these variables should all be purified (ran through 3rd party HTML purifier tool)
     * @var array
     */
    protected $purify = [];

    /**
     * When set, these variables should all be cleaned by stripping all tags
     * @var array
     */
    protected $strip_tags = [];

    /**
     * When set, these variables should all be cleaned by fitlering out everything except letters, numbers, and spaces
     * @var array
     */
    protected $alpha_num = [];

    /**
     * When set, these variables should all be cleaned by fitlering out everything except letters, numbers, dashes, spaces, and underscores
     * @var array
     */
    protected $alpha_dash = [];

    /**
     * When set, these variables should all be cleaned by filtering all but numbers
     * @var array
     */
    protected $integers = [];

    /**
     * Set a given attribute on the model.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @return mixed
     */
    public function setAttribute($key, $value)
    {
        parent::setAttribute($key, $value);

        if(in_array($key, $this->purify)) {
            //a helper from a 3rd party html sanitation library
            $this->attributes[$key] = clean($this->attributes[$key]);
            return $this;
        }

        if(in_array($key, $this->strip_tags)) {
            $this->attributes[$key] = strip_tags($this->attributes[$key]);
            return $this;
        }

        if(in_array($key, $this->alpha_num)) {
            $this->attributes[$key] = preg_replace('/[A-Za-z0-9 ]/', '', $this->attributes[$key]);
            return $this;
        }

        if(in_array($key, $this->alpha_dash)) {
            $this->attributes[$key] = preg_replace('/[^ \w-]/', '', $this->attributes[$key]);
            return $this;
        }

        if(in_array($key, $this->integers)) {
            $this->attributes[$key] = preg_replace('/\D/', '', $this->attributes[$key]);
            return $this;
        }

        return $this;
    }


}

The usage of the above model looks like this:

/**
 * Project Models
 */
class Project extends SanitizedModel
{
    protected $purify = [
        'body',
    ];

    protected $strip_tags = [
        'title',
        'type',
    ];

    protected $integers = [
        'privacy',
        'progress',
    ];
  //........
}

Any recommendations? I'm also open to suggestions of missing useful sanitation methods to improve what I'm trying to make into a catch-all solution if possible.

0 likes
1 reply
jlrdw's avatar

Most folks here will say using blade and validating.

Me I strip_tags on fields that need it.

To me validating doesn't work in many cases.

A field needs to be text only minimum 6. A person enters

Abcdef

So meaningless data was just validated.

Please or to participate in this conversation.