symfony/html-sanitizer
Object-oriented HTML sanitizer for PHP/Symfony. Safely cleans untrusted HTML for DOM insertion with configurable allow/block/drop rules, attribute policies, forced values, and URL controls (HTTPS and scheme/host allowlists). Removes scripts and unsafe behaviors.
Architecture Fit
HtmlSanitizer component, leveraging Laravel’s existing Symfony bridge (e.g., symfony/http-foundation). Aligns with Laravel’s security-first philosophy (e.g., Blade templating, form handling).<head>, <textarea>), critical for Laravel’s multi-context views (e.g., admin vs. public dashboards).Integration Feasibility
composer.json (Symfony components are first-class citizens). Example:
composer require symfony/html-sanitizer
Blade::directive('sanitize', function ($expression) {
return "<?php echo app(Symfony\Component\HtmlSanitizer\HtmlSanitizer::class)->sanitize($expression); ?>";
});
Usage: @sanitize($userHtml).Technical Risk
allowElement('script')) could reintroduce XSS. Mitigate with:
allowSafeElements() and whitelist only necessary tags.AttributeSanitizerInterface implementations may require deep PHP/DOM knowledge. Document edge cases (e.g., data-* attributes).Key Questions
<math> tags for educational apps)?Stack Fit
symfony/http-foundation (already in Laravel).<title> tags).Migration Path
/api/comments).HtmlSanitizerService provider.htmlspecialchars() with sanitize() in Blade templates.config/sanitizer.php.@sanitize directive for templates.Sanitizer facade for business logic.<head>).Compatibility
body) can store sanitized HTML.Sequencing
symfony/html-sanitizer to composer.json.config/sanitizer.php:
'default' => [
'allowed_elements' => ['p', 'a', 'b', 'i', 'u', 'em', 'strong'],
'allowed_attributes' => ['href', 'title', 'class'],
'force_https' => true,
],
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(HtmlSanitizer::class, function ($app) {
$config = (new HtmlSanitizerConfig())
->allowSafeElements()
->allowElement('a', ['href', 'title']);
return new HtmlSanitizer($config);
});
}
$sanitizer = app(HtmlSanitizer::class);
$safeHtml = $sanitizer->sanitize($userInput);
{!! app('sanitizer')->sanitize($comment->body) !!}
Maintenance
composer update symfony/*).config/sanitizer.php to track allowlist changes.Support
dd($sanitizer->sanitize($input, debug: true)) to inspect dropped elements.allowElement('custom-tag')) in a README.Scaling
<div><p>Unclosed tag.🔗 in URLs or attributes.Failure Modes
| Failure | Impact | Mitigation |
|---|---|---|
| Misconfigured allowlist | XSS vulnerabilities | Default-deny policy + code reviews. |
| PHP 8.4 parser regression | Sanitization failures | Fallback to MastermindsParser in config. |
| High CPU load | Slow responses | Cache configurations; offload to queues. |
| Custom sanitizer bugs | False positives/negatives | Unit tests with OWASP XSS payloads. |
| Dependency conflicts | Package installation failures | Isolate in a sanitizer namespace. |
Ramp-Up
AttributeSanitizerInterface.How can I help you explore Laravel packages today?