- What is stevebauman/purify and how does it prevent XSS in Laravel?
- stevebauman/purify is a thin Laravel service provider and facade wrapper around ezyang/htmlpurifier, the mature HTMLPurifier library. It sanitizes user-supplied HTML by stripping scripts, event handlers and other dangerous markup before you render it, which prevents stored and reflected XSS in rich-text surfaces such as comments, CMS bodies, support tickets and marketplace listings. You call Purify::clean() on a string or array, or bind sanitization to a model with the provided Eloquent casts.
- How do I install and configure stevebauman/purify in a Laravel application?
- Install it with composer require stevebauman/purify, then publish the configuration file using php artisan vendor:publish --provider="Stevebauman\Purify\PurifyServiceProvider". In the published config you define the allowed HTML for each content type or editor, and you can either call the facade directly or apply casts to models. No database schema changes are required if you sanitize on read.
- Which PHP and Laravel versions does stevebauman/purify support?
- The README lists PHP 7.4 or higher and Laravel 7.0 or higher, and the package works with Blade-rendered HTML as well as API JSON responses. Before adopting it, verify compatibility against your actual runtime, especially PHP 8.2+ and Laravel 11 or 12, since the wrapper version and the underlying HTMLPurifier version both matter. Pin the package version and run the package tests plus your own content-corpus tests on the target stack.
- Can stevebauman/purify clean arrays of user input as well as single strings?
- Yes. Purify::clean() accepts either a string or an array of user input and returns the same shape with every value sanitized, so you can clean a whole request payload in one call. Anything not on the allowlist, including disallowed inline styles and CSS classes, is stripped, so test representative editor output to confirm which markup survives.
- How do I sanitize HTML automatically on Eloquent models with Purify casts?
- Purify ships the PurifyHtmlOnGet and PurifyHtmlOnSet casts, which sanitize an HTML attribute as it is read from or written to the model. Register them in the $casts property on Laravel 10 and below, or in the casts() method on Laravel 11 and above. Read-time casts are a low-risk starting point because they avoid backfilling existing records, while write-time casts can reduce latency on render-heavy pages.
- How do I use a custom or named configuration for a single Purify call?
- You can pass a configuration name or inline configuration to a single call, and the package supports named config profiles along with custom HTML and CSS definitions for editors such as Trix or tightly constrained comment markup. This lets one application enforce different allowlists per content surface without duplicating setup. Keep ownership of allowlist changes explicit and reviewed, because they directly control what markup reaches your users.
- Does Purify cache HTMLPurifier definitions, and how do I clear or isolate that cache?
- HTMLPurifier builds definitions that are expensive to compute, so Purify caches them and exposes Purify::clear() to reset that cache. The README warns that clearing may issue Cache::clear() on the configured cache driver or wipe a configured filesystem directory, so point Purify at an isolated cache store or dedicated directory. Invalidate definitions whenever the allowed HTML or CSS changes, otherwise stale definitions keep enforcing the old policy.
- Is stevebauman/purify safe to use in production for user-generated HTML?
- Treat it as security-critical infrastructure: HTMLPurifier itself is mature and battle-tested, but the Laravel wrapper is a small, single-maintainer package with thin reported ecosystem adoption (538 stars but 0 dependents in the provided metadata). Accept that risk explicitly, keep the MIT-licensed code forkable, and verify PHP and Laravel compatibility on your stack. Misconfiguration can either permit XSS or silently strip legitimate content, so define a failure policy, test with real XSS payloads, and keep output escaping and CSP in place as defense in depth.
- Should I sanitize on read or on write, and how do I migrate existing content?
- Read-time sanitization through a Purify cast avoids a data migration and is the simplest way to protect existing records, while write-time sanitization can lower latency on high-traffic render paths. If you choose write time, backfill in idempotent batches and keep the original values until the output has been verified. When replacing an existing sanitizer, run both in parallel and diff the results before cutover.
- What are the alternatives to stevebauman/purify, and is it actively maintained?
- Alternatives include using ezyang/htmlpurifier directly, sanitizers bundled with larger CMS packages, or other Laravel sanitizer wrappers, and the right choice depends on how much configuration control and framework integration you need. The provided material makes no statement about long-term support, so check recent releases and CI status before depending on it in a security path. Given the small surface area, plan to fork it or wrap it behind an application-level sanitizer interface if maintenance stalls.