A simple Laravel service provider for easily using HTMLPurifier inside Laravel

Overview

HTMLPurifier for Laravel 5/6/7/8

Build Status codecov Latest Stable Version Latest Unstable Version License Total Downloads

A simple Laravel service provider for easily using HTMLPurifier inside Laravel. From their website:

HTML Purifier is a standards-compliant HTML filter library written in PHP. HTML Purifier will not only remove all malicious code (better known as XSS) with a thoroughly audited, secure yet permissive whitelist, it will also make sure your documents are standards compliant, something only achievable with a comprehensive knowledge of W3C's specifications. Tired of using BBCode due to the current landscape of deficient or insecure HTML filters? Have a WYSIWYG editor but never been able to use it? Looking for high-quality, standards-compliant, open-source components for that application you're building? HTML Purifier is for you!

Installation

For Laravel 5.5+

Require this package with composer:

composer require mews/purifier

The service provider will be auto-discovered. You do not need to add the provider anywhere.

For Laravel 5.0 to 5.4

Require this package with composer:

composer require mews/purifier

Find the providers key in config/app.php and register the HTMLPurifier Service Provider.

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

Find the aliases key in config/app.php and register the Purifier alias.

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

For Laravel 4

Check out HTMLPurifier for Laravel 4

Usage

Use these methods inside your requests or middleware, wherever you need the HTML cleaned up:

clean(Input::get('inputname'));

or

Purifier::clean(Input::get('inputname'));

dynamic config

clean('This is my H1 title', 'titles');
clean('This is my H1 title', array('Attr.EnableID' => true));

or

Purifier::clean('This is my H1 title', 'titles');
Purifier::clean('This is my H1 title', array('Attr.EnableID' => true));

use URI filter

Purifier::clean('This is my H1 title', 'titles', function (HTMLPurifier_Config $config) {
    $uri = $config->getDefinition('URI');
    $uri->addFilter(new HTMLPurifier_URIFilter_NameOfFilter(), $config);
});

Alternatively, in Laravel 7+, if you're looking to clean your HTML inside your Eloquent models, you can use our custom casts:



namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Mews\Purifier\Casts\CleanHtml;
use Mews\Purifier\Casts\CleanHtmlInput;
use Mews\Purifier\Casts\CleanHtmlOutput;

class Monster extends Model
{
    protected $casts = [
        'bio'            => CleanHtml::class, // cleans both when getting and setting the value
        'description'    => CleanHtmlInput::class, // cleans when setting the value
        'history'        => CleanHtmlOutput::class, // cleans when getting the value
    ];
}

Configuration

To use your own settings, publish config.

php artisan vendor:publish --provider="Mews\Purifier\PurifierServiceProvider"

Config file config/purifier.php should like this

[ "HTML.SafeIframe" => 'true', "URI.SafeIframeRegexp" => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/)%", ], 'custom_definition' => [ 'id' => 'html5-definitions', 'rev' => 1, 'debug' => false, 'elements' => [ // http://developers.whatwg.org/sections.html ['section', 'Block', 'Flow', 'Common'], ['nav', 'Block', 'Flow', 'Common'], ['article', 'Block', 'Flow', 'Common'], ['aside', 'Block', 'Flow', 'Common'], ['header', 'Block', 'Flow', 'Common'], ['footer', 'Block', 'Flow', 'Common'], // Content model actually excludes several tags, not modelled here ['address', 'Block', 'Flow', 'Common'], ['hgroup', 'Block', 'Required: h1 | h2 | h3 | h4 | h5 | h6', 'Common'], // http://developers.whatwg.org/grouping-content.html ['figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common'], ['figcaption', 'Inline', 'Flow', 'Common'], // http://developers.whatwg.org/the-video-element.html#the-video-element ['video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', [ 'src' => 'URI', 'type' => 'Text', 'width' => 'Length', 'height' => 'Length', 'poster' => 'URI', 'preload' => 'Enum#auto,metadata,none', 'controls' => 'Bool', ]], ['source', 'Block', 'Flow', 'Common', [ 'src' => 'URI', 'type' => 'Text', ]], // http://developers.whatwg.org/text-level-semantics.html ['s', 'Inline', 'Inline', 'Common'], ['var', 'Inline', 'Inline', 'Common'], ['sub', 'Inline', 'Inline', 'Common'], ['sup', 'Inline', 'Inline', 'Common'], ['mark', 'Inline', 'Inline', 'Common'], ['wbr', 'Inline', 'Empty', 'Core'], // http://developers.whatwg.org/edits.html ['ins', 'Block', 'Flow', 'Common', ['cite' => 'URI', 'datetime' => 'CDATA']], ['del', 'Block', 'Flow', 'Common', ['cite' => 'URI', 'datetime' => 'CDATA']], ], 'attributes' => [ ['iframe', 'allowfullscreen', 'Bool'], ['table', 'height', 'Text'], ['td', 'border', 'Text'], ['th', 'border', 'Text'], ['tr', 'width', 'Text'], ['tr', 'height', 'Text'], ['tr', 'border', 'Text'], ], ], 'custom_attributes' => [ ['a', 'target', 'Enum#_blank,_self,_target,_top'], ], 'custom_elements' => [ ['u', 'Inline', 'Inline', 'Common'], ], ], ];">
return [
    'encoding'           => 'UTF-8',
    'finalize'           => true,
    'ignoreNonStrings'   => false,
    'cachePath'          => storage_path('app/purifier'),
    'cacheFileMode'      => 0755,
    'settings'      => [
        'default' => [
            'HTML.Doctype'             => 'HTML 4.01 Transitional',
            'HTML.Allowed'             => 'div,b,strong,i,em,u,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/)%",
        ],
        'custom_definition' => [
            'id'  => 'html5-definitions',
            'rev' => 1,
            'debug' => false,
            'elements' => [
                // http://developers.whatwg.org/sections.html
                ['section', 'Block', 'Flow', 'Common'],
                ['nav',     'Block', 'Flow', 'Common'],
                ['article', 'Block', 'Flow', 'Common'],
                ['aside',   'Block', 'Flow', 'Common'],
                ['header',  'Block', 'Flow', 'Common'],
                ['footer',  'Block', 'Flow', 'Common'],
				
				// Content model actually excludes several tags, not modelled here
                ['address', 'Block', 'Flow', 'Common'],
                ['hgroup', 'Block', 'Required: h1 | h2 | h3 | h4 | h5 | h6', 'Common'],
				
				// http://developers.whatwg.org/grouping-content.html
                ['figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common'],
                ['figcaption', 'Inline', 'Flow', 'Common'],
				
				// http://developers.whatwg.org/the-video-element.html#the-video-element
                ['video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', [
                    'src' => 'URI',
					'type' => 'Text',
					'width' => 'Length',
					'height' => 'Length',
					'poster' => 'URI',
					'preload' => 'Enum#auto,metadata,none',
					'controls' => 'Bool',
                ]],
                ['source', 'Block', 'Flow', 'Common', [
					'src' => 'URI',
					'type' => 'Text',
                ]],

				// http://developers.whatwg.org/text-level-semantics.html
                ['s',    'Inline', 'Inline', 'Common'],
                ['var',  'Inline', 'Inline', 'Common'],
                ['sub',  'Inline', 'Inline', 'Common'],
                ['sup',  'Inline', 'Inline', 'Common'],
                ['mark', 'Inline', 'Inline', 'Common'],
                ['wbr',  'Inline', 'Empty', 'Core'],
				
				// http://developers.whatwg.org/edits.html
                ['ins', 'Block', 'Flow', 'Common', ['cite' => 'URI', 'datetime' => 'CDATA']],
                ['del', 'Block', 'Flow', 'Common', ['cite' => 'URI', 'datetime' => 'CDATA']],
            ],
            'attributes' => [
                ['iframe', 'allowfullscreen', 'Bool'],
                ['table', 'height', 'Text'],
                ['td', 'border', 'Text'],
                ['th', 'border', 'Text'],
                ['tr', 'width', 'Text'],
                ['tr', 'height', 'Text'],
                ['tr', 'border', 'Text'],
            ],
        ],
        'custom_attributes' => [
            ['a', 'target', 'Enum#_blank,_self,_target,_top'],
        ],
        'custom_elements' => [
            ['u', 'Inline', 'Inline', 'Common'],
        ],
    ],

];

Change log

Please see the Github Releases Tab for more information on what has changed recently.

Security

If you discover any security related issues, please email the author instead of using the issue tracker.

Credits

License

MIT. Please see the license file for more information.

Comments
  • Laravel 5 compatibility

    Laravel 5 compatibility

    Due to the illuminate/support": "4.*" requirement in composer.json, this package doesn't work with laravel 5 :-( Mind adding support to it?

    opened by Yannik 10
  • Adds support for Laravel 9

    Adds support for Laravel 9

    Hey @mewebstudio ,

    Laravel 9 is just around the corner (due in 5 days). I thought we'd get ahead of this thing, and provide support before it's out. Tested this package against L9 and... what do you know, everything still works great 🎉 So it only needs a dependency version bump to support L9. That's what this PR does.

    Again, thanks for a great package. Cheers!

    PS. My only concern in terms of breaking changes was this one but it seems it's all fine, clean(null) works jus as well as clean(''). So we're good 💪

    opened by tabacitu 7
  • Laravel 5.0.17 | Call to undefined method [package]

    Laravel 5.0.17 | Call to undefined method [package]

    Hello, just upgraded to Laravel version 5.0.17 and now Purifier seems not to work. I get the error "Call to undefined method [package]"

    Hope this can be solved soon, thanks :+1:

    opened by eklundkristoffer 7
  • Fix custom definitions and custom elements

    Fix custom definitions and custom elements

    I removed call of HTMLPurifier_Config::inherit() because inherited config object doen't use custom definitions from parent one.

    Also creating of config object for purifier was heavilly refactored. All related stuff moved to separate class. Another problem is that HTMLPurifier library ignore any custom elements if HTML.Allowed or HTML.AllowedElements provided in config. So we need to duplicate each custom element name in this properties. I made this to be done automatically. So now if there is a custom elements defined in cofig - they will be appended to the list of HTML.Allowed or HTML.AllowedElements depending of which is provided.

    Also creating of config object moved to clean() method if custom config provided. This makes posible to use custom elements even with dynamic configuration.

    Fixed old tests and added some new ones.

    Please review and let me know if something must be fixed.

    P.S. Sorry for my english, I'm just studying it.

    opened by zarianec 6
  • prevent Purifier from stripping

    prevent Purifier from stripping "target"

    No matter what I do Purifier strips "target" attribute for <a>. My code looks like this

    return [
    
        'encoding' => 'UTF-8',
        'finalize' => true,
        'preload'  => false,
        'cachePath' => null,
        'settings' => [
            'default'          => [
                'HTML.Doctype'             => 'HTML 4.01 Transitional',
                'Attr.AllowedFrameTargets' => '_blank',
                'Attr.AllowedRel'          => 'nofollow',
    
                'HTML.Allowed'             => 'h2,strike,blockquote,u,div,b,strong,i,em,a[href|title|target|rel],ul,ol,li,p,br,span,img[width|height|alt|src]',
                'CSS.AllowedProperties'    => 'font,font-weight,font-style,text-decoration,padding-left,text-align',
                'AutoFormat.AutoParagraph' => false,
                'AutoFormat.RemoveEmpty'   => true,
            ],
            'test' => [
                'Attr.EnableID' => true
            ],
            "youtube" => [
                "HTML.SafeIframe" => 'true',
                "URI.SafeIframeRegexp" => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/)%",
            ],
        ],
    
    ];
    

    What am I doing wrong? I have gone through all the open and closed issues and tried everything that I thought would work, but no luck. Any help will be super greatly appreciated

    opened by Shigeki1120 6
  • "preload" config option superfluous?

    I can't find the preload config option referenced anywhere in the code, other than in the example config file. Was it intended for a future feature? Seems like it should be removed.

    opened by hackel 6
  • ErrorException

    ErrorException

    Added this package to my project, with no config, attempted to test the results and it produced an error.

    Using Laravel 4.1

    Here's my code in my controller: $template->template = Purifier::clean(Input::get('template'));

    I use ckEditor, I went into view source and added some malicious code found on the HTMLPurifier site located at http://htmlpurifier.org/demo.php?html=%3Cimg+src%3D%22javascript%3Aevil%28%29%3B%22+onload%3D%22evil%28%29%3B%22+%2F%3E

    When I attempted to see if HMLPurifier would remove it, it produced the error: Directory "/var/www/project/vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/Serializer not writable, please chmod to 777"

    The section of code it's failing on is: /var/www/speakeasy/vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/Serializer.php (line 272) // need to give global permissions $chmod = $chmod | 0777; } trigger_error( 'Directory ' . $dir . ' not writable, ' . 'please chmod to ' . decoct($chmod), E_USER_WARNING ); } else { // generic error message

    Not sure why it is attempting to write to the folder under "vendor". Is this something that can be fixed?

    bug 
    opened by mpemberton5 6
  • Fix custom definitions

    Fix custom definitions

    It looks like HTMLPurifier_Config::inherit($config) that used when creating purifier instance, doesn't use custom definitions from parent config object.

    I changed it to use config object directly.

    opened by zarianec 5
  • Laravel *OR* Lumen

    Laravel *OR* Lumen

    Hi @mewebstudio , I this that's worth noticing that actually automated tests cannot be run. In composer.json neither Laravel nor Lumen are required so that tests all error. Cause is here: #34

    Solution could be to create two separate packages, one for Laravel and the other for Lumen. Another way is to customize the scripts before the tests to require Laravel.

    What do you think?

    opened by micheleangioni 5
  • Update to allow custom HTML elements definitions

    Update to allow custom HTML elements definitions

    Just added an special option "definitions" in the config which allows to set custom HTML definitions, in order to add support of elements and attributes, like:

    or [allowfullscreen] for an iframe.

    opened by Madnx 5
  • Laravel 9.x Compatibility

    Laravel 9.x Compatibility

    This is an automated pull request from Shift to update your package code and dependencies to be compatible with Laravel 9.x.

    Before merging, you need to:

    • Checkout the l9-compatibility branch
    • Review all comments for additional changes
    • Thoroughly test your package

    If you do find an issue, please report it by commenting on this PR to help improve future automation.

    opened by laravel-shift 4
  • PHP 8.2 Support

    PHP 8.2 Support

    Can you update the mews/purifier package to support the 8.2 php version?

    Current issue:

     Problem 1
        - mews/purifier[3.3.0, ..., 3.3.2] require php ^7.2 -> your php version (8.2.0RC7) does not satisfy that requirement.
        - mews/purifier[3.3.3, ..., 3.3.6] require illuminate/config ^5.8|^6.0|^7.0|^8.0 -> found illuminate/config[v5.8.0, ..., 5.8.x-dev, v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.
        - mews/purifier[3.3.7, ..., 3.3.8] require ezyang/htmlpurifier 4.13.* -> found ezyang/htmlpurifier[v4.13.0] but it conflicts with your root composer.json require (^4.16).
        - Root composer.json requires mews/purifier ^3.3 -> satisfiable by mews/purifier[3.3.0, ..., 3.3.8].
    
    opened by Ognj3n 0
  • PHP 8.1 Support

    PHP 8.1 Support

    Can you upgrade ezyang/htmlpurifier version? Your package currently incompatible with php 8.1

    Problem 1
        - mews/purifier[3.3.0, ..., 3.3.2] require php ^7.2 -> your php version (8.1.12) does not satisfy that requirement.
        - mews/purifier[3.3.3, ..., 3.3.6] require illuminate/config ^5.8|^6.0|^7.0|^8.0 -> found illuminate/config[v5.8.0, ..., 5.8.x-dev, v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.
        - mews/purifier[3.3.7, ..., 3.3.8] require ezyang/htmlpurifier 4.13.* -> found ezyang/htmlpurifier[v4.13.0] but the package is fixed to v4.16.0 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
        - Root composer.json requires mews/purifier ^3.3 -> satisfiable by mews/purifier[3.3.0, ..., 3.3.8].
    
    opened by BurakBoz 0
  • CleanHtml cast returns an empty string when database value is null

    CleanHtml cast returns an empty string when database value is null

    I have a field in database, i.e. html_content. The field is nullable and by default is null, but it may contain some HTML content.

    Model casts this field using CleanHtml class and the result of $model->html_content when html_content is null is an empty string, instead of null value.

    Isn't it supposed to return null value, because null value may indicate certain things when rendering pages on the front-end, etc.?

    opened by lyyka 0
  • Conflict with package PHPOffice/PhpSpreadsheet

    Conflict with package PHPOffice/PhpSpreadsheet

    Which also uses "ezyang/htmlpurifier": "^4.13"

    Using version ^3.3 for mews/purifier

    Your requirements could not be resolved to an installable set of packages.

    Problem 1 - mews/purifier[3.3.0, ..., 3.3.8] require ezyang/htmlpurifier 4.13.* -> found ezyang/htmlpurifier[v4.13.0] but the package is fixed to v4.14.0 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command. - Root composer.json requires mews/purifier ^3.3 -> satisfiable by mews/purifier[3.3.0, ..., 3.3.8].

    opened by howdu 1
  • Old version of ezyang/htmlpurifier

    Old version of ezyang/htmlpurifier

    Is it intended that version 3.3.8 of mews/purifier still uses old version of ezyang/htmlpurifier (4.13.0)? Version 4.14.0 was released in December 2021.

    opened by maciek-szn 0
Releases(3.3.9)
Owner
MeWebStudio - Muharrem ERİN
MeWebStudio - Muharrem ERİN
A laravel service provider for the netsuite-php library service

netsuite-laravel A PHP supplemental package to the ryanwinchester/netsuite-php package to add the NetSuite service client to the service container of

NetsuitePHP 6 Nov 9, 2022
Laravel Lumen service provider for Understand.io

The service provider is deprecated - it does not support error grouping. Laravel Lumen service provider for Understand.io You may also be interested i

null 6 May 30, 2019
A package that uses blade templates to control how markdown is converted to HTML inside Laravel, as well as providing support for markdown files to Laravel views.

Install Install via composer. $ composer require olliecodes/laravel-etched-blade Once installed you'll want to publish the config. $ php artisan vendo

Ollie Codes 19 Jul 5, 2021
Log activity inside your Laravel app

Log activity inside your Laravel app The spatie/laravel-activitylog package provides easy to use functions to log the activities of the users of your

Spatie 4.6k Jan 7, 2023
A REST client inside your Laravel app

Laravel Compass is an elegant REST assistant for the Laravel framework that you can use to test API calls and create API documentation. it provides automatically endpoints for GET, POST, PUT/PATCH, DELETE, various auth mechanisms, and other utility endpoints based on Laravel routes in your project.

David H. Sianturi 1.2k Dec 31, 2022
Filament-spatie-laravel-activitylog - View your activity logs inside of Filament. ⚡️

View your activity logs inside of Filament. This package provides a Filament resource that shows you all of the activity logs created using the spatie

Ryan Chandler 45 Dec 26, 2022
Declare routes inside Laravel Livewire components.

Convoy This package allows you to declare routes inside of your full page Laravel Livewire components. All you have to do is create a route method ins

null 17 Jul 27, 2022
Declare database migrations and factory definitions inside Laravel models.

Lucid This package allows you to declare database migrations and factory definitions inside of your Laravel models. Running the lucid:migrate command

null 23 Jul 9, 2022
Bootstrap Theme Generator inside of a Wordpress-Settings-Page. Includes live compilation of SCSS!

Bootstrap-Theme-Generator Bootstrap Theme Generator enables you to choose which components of Bootstrap you want to load. It also gives you the possib

null 3 Aug 15, 2022
Mollie API client wrapper for Laravel & Mollie Connect provider for Laravel Socialite

Mollie for Laravel Laravel-Mollie incorporates the Mollie API and Mollie Connect into your Laravel or Lumen project. Accepting iDEAL, Apple Pay, Banco

Mollie 289 Nov 24, 2022
Driver for managing cash payments in the Cashier Provider ecosystem

Cash Driver Provider Installation To get the latest version of Cash Driver Provider, simply require the project using Composer: $ composer require cas

Cashier Provider 4 Aug 30, 2022
UnifiedPush provider for Nextcloud - server application

NextPush - Server App UnifiedPush provider for Nextcloud - server application This is still a WIP version Requirement It require the nextcloud server

NextPush 38 Jan 5, 2023
A simple package to manage the creation of a structure composed of the service and repository layers in a Laravel application

Chapolim Este projeto tem como objetivo fornecer alguns comandos adicionais à interface de linha de comando do Laravel, o Artisan, para manipular a es

Eliezer Alves 51 Dec 11, 2022
A simple artisanal command framework for creating service layer classes

Introdução Este projeto tem como objetivo fornecer alguns comandos adicionais à interface de linha de comando do Laravel para manipular a estrutura da

Eliezer Alves 15 Feb 2, 2022
Easily add a full Laravel blog (with built in admin panel and public views) to your laravel project with this simple package.

Webdevetc BlogEtc - Complete Laravel Blog Package Quickly add a blog with admin panel to your existing Laravel project. It has everything included (ro

WebDevEtc. 227 Dec 25, 2022
A package to easily make use of Simple Icons in your Laravel Blade views.

Blade Simple Icons A package to easily make use of Simple Icons in your Laravel Blade views. For a full list of available icons see the SVG directory.

UB Labs 12 Jan 17, 2022
MediaDB is a web-based media streaming service written in Laravel and Vue.

MediaDB (API) MediaDB is a web-based media streaming service written in Laravel and Vue. The nginx-vod-module is used for on-the-fly repackaging of MP

François M. 53 Sep 3, 2022
Laravel 4.* and 5.* service providers to handle PHP errors, dump variables, execute PHP code remotely in Google Chrome

Laravel 4.* service provider for PHP Console See https://github.com/barbushin/php-console-laravel/releases/tag/1.2.1 Use "php-console/laravel-service-

Sergey 73 Jun 1, 2022
Load Laravel service providers based on your application's environment.

Laravel EnvProviders A more finetuned way of managing your service providers in Laravel. This package allows you to configure the environment certain

Sven Luijten 79 Dec 29, 2022