Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Html Sanitizer Bundle Laravel Package

tgalopin/html-sanitizer-bundle

Symfony bundle integrating the html-sanitizer library so you can define and configure HTML sanitizers as services, clean untrusted markup safely, and use customizable sanitizer profiles throughout your application.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit: This is a Symfony bundle (tgalopin/html-sanitizer-bundle) that wires the framework-agnostic tgalopin/html-sanitizer library into Symfony's DI container and configuration system. It is not a Laravel package — there is no service provider, no publishable config, no facade. For a Laravel codebase the realistic architecture is: depend on the underlying sanitizer library directly, bind a configured HtmlSanitizerInterface singleton in a small SanitizerServiceProvider, and drive allowlists from config/sanitizer.php. The bundle's release activity is still useful signal — it tells us the upstream sanitizer API is stable and receiving compatibility work — but the bundle artifact itself should not be installed in a Laravel app.

Integration feasibility: High for the library, low for the bundle. The 1.4.0 changes are relevant in three ways: (1) Symfony 6 support confirms the package is still maintained against modern PHP/Symfony component versions, which matters indirectly because Laravel pulls in symfony/console, symfony/http-foundation, etc.; (2) the missing-return-type deprecation fix reduces noise on PHP 8.1+; (3) the env-override fix for the config key is genuinely useful for 12-factor deployments — sanitizer profiles can now differ per environment without config edits. None of these are blockers or enablers for a Laravel integration.

Technical risk: The dominant risk is upstream lifecycle, not this release. The underlying tgalopin/html-sanitizer line has been superseded in the ecosystem by symfony/html-sanitizer, and a bundle that only just reached Symfony 6 support in 1.4.0 suggests reactive rather than proactive maintenance. Secondary risks: the new details extension expands the allowed-markup surface (the open attribute and nested summary content are new vectors to validate); the env-override change alters configuration precedence, so any environment relying on the old behaviour will silently change; and the return-type fix implies the codebase previously emitted deprecations, so a E_DEPRECATED-as-error CI policy could have been masking issues.

Key questions:

  • Is tgalopin/html-sanitizer formally deprecated, and if so what is our exit path to symfony/html-sanitizer?
  • Does the sanitizer version required by bundle 1.4.0 pin a PHP floor above our oldest supported runtime?
  • Does the details extension permit attribute injection via open, and has it been fuzzed?
  • What is our XSS regression corpus, and does it cover the newly allowed elements?
  • Which environments currently depend on the pre-1.4.0 config-key precedence?
  • Is there an existing community Laravel bridge, or do we own the adapter?

Integration Approach

Stack fit: Target Laravel 9/10/11 on PHP 8.1+. Consume tgalopin/html-sanitizer (or symfony/html-sanitizer) as a library. Implement a SanitizerServiceProvider that reads config/sanitizer.php, constructs a HtmlSanitizer with our extension set, and registers it as a singleton behind an interface so it can be swapped or mocked. Do not install the bundle — its service definitions will not load and it adds a transitive Symfony framework constraint for no benefit.

Migration path: Inventory every current sanitization call site (strip_tags, htmlspecialchars on trusted-HTML fields, any HTMLPurifier usage, Blade {!! !!} sinks). Classify each as a read path (render) or write path (persist). Migrate write paths first so stored data is clean, then read paths. Build a golden-file test suite of representative and malicious payloads before swapping any call site, and run old and new sanitizers in parallel on production traffic (log-only) to diff output for a week.

Compatibility: Symfony 6 support in the bundle is irrelevant to a Laravel install; what matters is the sanitizer library's PHP constraint and its dependency on symfony/css-selector/masterminds/html5. Verify our Laravel version's Symfony component pins do not conflict. The return-type fix removes a deprecation that would surface under PHP 8.1+ with strict error reporting, so 1.4.0 is a mild compatibility improvement even for library-only consumers.

Sequencing:

  1. Spike (1–2 days): library-only prototype, confirm allowlist expresses our current policy.
  2. Adapter + config + interface, with feature flag.
  3. XSS corpus and golden-file tests, including details/summary cases if we enable that extension.
  4. Shadow-mode logging in one service, diff against incumbent.
  5. Cut over write paths, then read paths, then remove the old helper.
  6. Pin the version and document the upstream-deprecation watch item.

Operational Impact

Maintenance: Small dependency surface and low release cadence — roughly four PRs in this cycle, all small. Cost is dominated by allowlist curation, not code. The real maintenance burden is governance: we must track whether the upstream sanitizer is archived and hold a documented migration path to symfony/html-sanitizer. Budget a recurring quarterly review rather than continuous work.

Support: No first-party Laravel support and no vendor SLA. Ownership sits with the platform/backend team. Internal documentation should cover how to add an allowed tag or attribute, since that will be the most frequent request and the most security-sensitive change. Expect ad-hoc requests from content and marketing teams for markup we deliberately disallow.

Scaling: Sanitization is in-process and CPU-bound on string parsing; it scales horizontally with the app tier and adds no external dependency, which is a genuine advantage over a sidecar or API-based sanitizer. Two caveats: cache the constructed sanitizer/config per process (do not rebuild per request), and cap input size before parsing — pathological HTML is a CPU-exhaustion vector. For bulk import or backfill jobs, run sanitization in queue workers with a memory limit rather than in web requests.

Failure modes:

  • Over-permissive allowlist → stored XSS; highest-severity, detected only by security review.
  • Over-restrictive allowlist → silent content mangling on save; data loss that is hard to reverse.
  • Env-override config change (1.4.0) → environments diverge in policy without a code change; staging may allow markup production strips. Add a startup assertion that logs the effective profile per environment.
  • details extension misconfiguration → unexpected attributes surviving; validate before enabling.
  • Deprecation noise on PHP upgrades → mitigated by the return-type fix, but re-check on each PHP minor.
  • Upstream abandonment → no security patches; mitigated by the documented fork/switch plan.

Ramp-up: A mid-level Laravel developer can integrate the library in under a day. The non-obvious learning is the extension model — writing a custom extension to permit a specific tag/attribute combination, and understanding that an extension granting an attribute on an element effectively grants it everywhere that element appears. Allocate one to two days of security-oriented pairing for whoever owns the allowlist, and require a second reviewer on any change to it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core