symfony/html-sanitizer
Symfony HtmlSanitizer provides an OO API to clean untrusted HTML for safe DOM insertion. Configure allowed/blocked elements and attributes, drop or keep children, force attributes, enforce HTTPS, and restrict link schemes/hosts to prevent XSS and unsafe behavior.
strip_tags, regex-based filters).sanitizeFor('head'), sanitizeFor('textarea')), which is essential for Laravel’s dynamic rendering (e.g., Blade templates, API responses).HTMLPurifier.HtmlSanitizerServiceProvider), exposing a facade (HtmlSanitizer::sanitize()) for consistency with Laravel’s ecosystem.SanitizeInputMiddleware) to protect against XSS in API payloads or form submissions.@sanitize) could simplify usage in templates:
Blade::directive('sanitize', fn($expr) => "<?php echo app('sanitizer')->sanitize($expr); ?>");
Usage: @sanitize($userInput).HTMLPurifier or DOMDocument for critical paths.MastermindsParser (deprecated in Symfony 8.0+).javascript: in URLs) could introduce vulnerabilities. Automated testing (e.g., OWASP ZAP) is critical.head, textarea) be managed across the app?laravel-html) that could interfere?MastermindsParser (minor performance hit).HttpFoundation for request sanitization).| Package | Pros | Cons | Fit for Laravel? |
|---|---|---|---|
HTMLPurifier |
Feature-rich, battle-tested | Heavy, complex config | Medium |
DOMDocument |
Native PHP, simple | Manual parsing, error-prone | Low |
symfony/html-sanitizer |
Lightweight, modern, flexible | Newer, fewer docs | High |
strip_tags or regex-based sanitizers with HtmlSanitizer.// Before
$clean = strip_tags($userInput, '<p><b><i>');
// After
$config = (new HtmlSanitizerConfig())->allowSafeElements();
$clean = app(HtmlSanitizer::class)->sanitize($userInput, $config);
SanitizePayloadMiddleware).public function handle(Request $request, Closure $next) {
$request->merge([
'sanitized_content' => $this->sanitizer->sanitize($request->input('content'))
]);
return $next($request);
}
Blade::directive('safeHtml', function ($expr) {
return "<?php echo e(app('sanitizer')->sanitize({$expr})); ?>";
});
public function rules() {
return ['content' => 'required|sanitized']; // Custom rule
}
protected function sanitized($attribute, $value, $fail) {
$sanitized = app(HtmlSanitizer::class)->sanitize($value);
$fail($sanitized !== $value ? 'Invalid HTML detected.' : '');
}
laravel-html, Purifier, or DOMDocument if used selectively.symfony/cache) can optimize repeated sanitization.text columns).AppServiceProvider:
public function register() {
$this->app->singleton(HtmlSanitizer::class, fn() => new HtmlSanitizer(
(new HtmlSanitizerConfig())->allowSafeElements()
));
}
config/sanitizer.php) and allow per-context overrides.public function test_xss_sanitization() {
$sanitizer = app(HtmlSanitizer::class);
$malicious = '<script>alert(1)</script>';
$clean = $sanitizer->sanitize($malicious);
$this->assertEmpty(trim($clean));
}
$sanitizer->sanitize($input, $config, ['log' => true]);
config/sanitizer.php with env() overrides) and version-controlled defaults.symfony/flex or `How can I help you explore Laravel packages today?