How to use Laravel Purifier for improved site security

,

Intro

As I was building this new Kuztek site I wanted to build it to the same standards I would if I were building it for any client and that means protecting the site from malicious code or security threats. I may be the only one adding content to this site or modifying what is in the database, but filtering what we are outputting to the browser to make sure it doesn’t harm the site or our users just makes sense. We don’t want to leave our sites vulnerable to Cross-Sites Scripting(XSS). This tutorial covers Laravel customization and is intended to be used by developers to improve their site security.

When using Laravel Blade templates we typically would output content doing something like this:

Hello, {{ $name }}. 

The double curly brackets used in Blade indicate that the content will be escaped and any html code that would have been outputted will be removed automatically. But what if we want some html to come through from our database but not anything that would be a security risk? We searched around for some existing code to do the job because writing something from scratch could take a lot of time. Enter HTMLPurifier, a well maintained tool that cleans up code and even fixes things like missing html tags or illegal html nesting. To get HTMLPurifier into our Laravel project we used a handy package from MeWebStudio and added it to our site using composer.

Lets get started with using Purifier in Laravel 5.

1. Add Purifier to your composer

Modify your composer.json

{ 
    "require": { 
        "laravel/framework": "~5.0", 
        "mews/purifier": "~2.0", 
    } 
} 

OR

Require the package using the command line:

composer require mews/purifier 

Then update your composer packages with:

composer update 

2. Set the providers and aliases in your Laravel application config

Open your app/config/app.php and add the HTMLPurifier Service Provider:

'providers' => [ 
        // ... 
        Mews\Purifier\PurifierServiceProvider::class, 
    ] 

Then find the aliases in the same app/config/app.php file:

'aliases' => [ 
        // ... 
        'Purifier' => Mews\Purifier\Facades\Purifier::class, 
    ] 

3. Configuration of Purifier

The default configuration for Purifier allows particular html elements and attributes to be used and some css styling as well.

If you want to make changes to the default configuration you can easily customize the configuration by publishing the configuration script using the command line:

php artisan vendor:publish 

This creates a new file at config/purifier.php that will look something like this:

return [ 

    'encoding' => 'UTF-8', 
    'finalize' => true, 
    'preload'  => false, 
    'cachePath' => null, 
    'settings' => [ 
        'default' => [ 
            'HTML.Doctype'             => 'XHTML 1.0 Strict', 
            'HTML.Allowed'             => 'div,b,strong,i,em,a[href|title],ul,ol,li,p[style],br,span[style],img[width|height|alt|src]', 
            'CSS.AllowedProperties'    => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align', 
            'AutoFormat.AutoParagraph' => true, 
            'AutoFormat.RemoveEmpty'   => true 
        ], 
        'test' => [ 
            'Attr.EnableID' => true 
        ], 
        "youtube" => [ 
            "HTML.SafeIframe" => 'true', 
            "URI.SafeIframeRegexp" => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/)%", 
        ], 
    ], 

]; 

The key things you may want to customize here are the HTML.Allowed and the CSS.AllowedProperties.

The HTMLPurifier documentation covers the HTML.Allowed in detail at http://htmlpurifier.org/live/configdoc/plain.html#HTML.Allowed but basically this configuration line is setting a whitelist of html elements you are allowing to be outputted and any attributes that those specific elements may have. By default a link can have href and title attributes and a paragraph can have a style attribute.

After you have the Purifier added to your site and you have adjusted your Blade templates to filter your content you may find that you need to adjust your Purifier configuration to allow or restrict more html tags and attributes. Initially I used the default Purifier config but quickly discovered it was filtering out my heading tags and some attributes I like to use(such as class or style) so we added them to our configuration.

This is what our HTML.Allowed looks like after modification:

'HTML.Allowed'  => 'h1[class],h2[class],h3[class],h4[class],h5[class],div[class],b,strong,i,em,a[href|title|class],ul,ol,li,p[style|class],br,span[style|class],img[width|height|alt|src|class]', 

4. Using the Purifier in your Blade templates

In a blade template we would use Purifier like this to clean the body of a blog post:

{{ clean( $body ) }} 

This will take our piece of data and run it through the HTMLPurifier and based on our configuration will remove any unapproved html elements or attributes and clean up the code so it is standards compliant.

We are here to help

If you have any questions about implementing the HTMLPurifier in Laravel feel free to hit us up on Twitter.

Additional Resources:

https://github.com/mewebstudio/Purifier

http://htmlpurifier.org/live/configdoc/plain.html

https://laravel.com/docs/5.0/templates

https://en.wikipedia.org/wiki/Cross-sites_scripting

https://www.acunetix.com/websitesecurity/cross-site-scripting/