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

Laravel Html Sanitizer Laravel Package

jeffersongoncalves/laravel-html-sanitizer

A Laravel package for sanitizing untrusted HTML before rendering. It helps remove dangerous tags and attributes to reduce XSS risks, with configurable rules for safely handling user-generated content in your applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. jeffersongoncalves/laravel-html-sanitizer is a thin Laravel service-provider wrapper around a PHP HTML sanitization engine. Architecturally it slots into the framework's standard package contract — auto-discovered provider, publishable config, facade/helper surface — so it does not impose a structural opinion on the application. That is the right shape for a cross-cutting concern like output sanitization: it is adoptable at the edges (controllers, form requests, Blade) without refactoring domain code. It is a utility package, not a platform component; treat it as one interchangeable dependency in the XSS-defense layer rather than as a trust boundary you build around.

Integration feasibility. Low. In a standard Laravel app this is a composer require plus php artisan vendor:publish plus an allowlist of permitted tags/attributes. No database migrations, no queue workers, no external services. A competent Laravel engineer can produce a working spike in under a day. The real effort is not integration but policy: deciding which content fields are rich text, what each field is allowed to contain, and whether sanitization happens on write (stored clean) or read (cleaned at render). That decision is product- and compliance-driven, not technical.

Technical risk. Three concerns, in order:

  1. Release opacity. v1.2.0 ships with release notes consisting solely of a v1.1.1...v1.2.0 changelog URL — no description of added features, changed defaults, dependency bumps, or deprecations. Semver minor implies backwards-compatible additive change, but that is an inference, not a stated guarantee. We cannot assess upgrade safety from the artifact provided.
  2. Single-maintainer concentration. The package is published from an individual maintainer's namespace with a large portfolio of small, similarly-scoped packages. Bus factor is 1. If maintenance lapses, our fallback is to inline the sanitization call directly against the underlying engine — which is why the wrapper must not become load-bearing in application code. Keep it behind our own thin abstraction.
  3. Engine inheritance. The security posture is really the posture of the underlying sanitizer library (HTMLPurifier, Symfony HTML Sanitizer, or similar). Sanitizers are a recurring CVE target; our actual patch obligation is to the engine, and the wrapper's release cadence may lag it.

Key questions. What sanitization engine does the package depend on, at what version constraint, and does v1.2.0 change that constraint? What exactly changed in v1.2.0 — configuration keys, default allowlist, facade signature, minimum Laravel/PHP? Does the config support multiple named profiles (e.g. comment vs article) or is it a single global allowlist? Is there a validation rule and a Blade directive, or only a facade? What is the Laravel/PHP support matrix, and is Laravel 12 / PHP 8.4 covered? Who is the upstream engine maintainer and what is its CVE history and release cadence? Does the package do anything beyond strip_tags-class filtering — specifically, does it neutralize javascript: URIs, on* handlers, and CSS-based vectors? Is the diff between v1.1.1 and v1.2.0 small enough for our engineer to review line-by-line before adoption?

Integration Approach

Stack fit. Fits any conventional Laravel application using Blade or an API layer, and is particularly relevant where users submit HTML: rich-text editor fields, comment bodies, CMS article content, imported RSS/email HTML, and any field rendered unescaped via {!! !!}. It is not a substitute for contextual output escaping — Blade's {{ }} remains the default control, and this package only applies where raw HTML is a genuine product requirement. For a pure-JSON API with no rich-text surface, the package is unnecessary; do not add it speculatively.

Migration path. There is no migration — greenfield addition, and removal is a one-line composer change if it stays behind an internal boundary. Recommended: define an application-level interface (e.g. HtmlSanitizer contract with a clean(string $html, string $profile): string method) and bind the package's implementation to it in a service provider. Swapping to mews/purifier, Symfony's sanitizer, or a direct engine call then becomes a one-class change and the vendor package never appears in domain code.

Compatibility. Verify minimum PHP and Laravel versions against our support matrix before committing; a minor bump is the most likely point at which a minimum-version floor moves. Pin to ^1.2 rather than *, commit the lockfile, and read the v1.1.1→v1.2.0 diff in CI-gated review rather than accepting the changelog link at face value. If the diff touches the default allowlist, treat it as a behavior change requiring regression testing regardless of the version number.

Sequencing.

  1. Spike (week 1). Install, publish config, sanitize a fixture corpus of known-malicious payloads (XSS cheat-sheet set) and known-legitimate rich text. Confirm the allowlist is neither too permissive nor destructive.
  2. Abstraction (week 1). Introduce the internal contract and binding; add unit tests against the contract so the implementation is replaceable.
  3. Pilot (weeks 2–3). Apply to the single highest-risk field — typically user comments or profile bios — with write-time sanitization.
  4. Policy definition (parallel). Write down per-field allowlists as reviewable config, not inline arrays. This is the durable artifact; the package is not.
  5. Rollout (weeks 4–6). Extend to remaining rich-text fields. Backfill-queue any historical content that was stored pre-sanitization, since write-time cleaning does nothing for existing rows.
  6. Observe and pin. After one full cycle, lock the minor version and schedule a quarterly review of upstream engine advisories.

Operational Impact

Maintenance. Low ongoing cost, but non-zero: a single dependency to patch, plus the underlying engine. Budget for a quarterly check of both. Because the maintainer publishes many small packages, expect occasional major-version churn across the portfolio and read every changelog rather than relying on automated minor-bumps. The v1.2.0 release, with no described contents, is a mild signal that release hygiene is informal — plan for the possibility that we are the ones documenting behavior for our own repo.

Support. Community-only. No SLA, no vendor, GitHub issues as the sole channel. Acceptable for a utility dependency, unacceptable if it were on the critical path of a regulated workflow. Ensure the internal abstraction and test suite mean an unanswered upstream issue never blocks a release on our side.

Scaling. Sanitization is CPU-bound string processing — negligible per request at typical volumes, measurable in bulk import or backfill jobs. Two mitigations: sanitize on write so the cost is paid once rather than on every render, and cache the cleaned output for high-traffic read paths. For large historical backfills, run through queued jobs with bounded batch sizes rather than a synchronous artisan command against a live table.

Failure modes. (a) Silent over-stripping — a config change quietly removes legitimate markup, discovered by users rather than tests. Mitigate with a golden-file test corpus of real content. (b) Under-sanitization — a new field added without a profile falls through to a permissive default; make the permissive default fail closed. (c) Engine CVE — an upstream advisory leaves us exposed until the wrapper releases; track the engine directly so we can patch independently. (d) Double-sanitization — cleaning both on input and on output mangles already-escaped entities; decide once and document it. (e) Config drift across environments if the config file is published and edited per-environment; keep allowlists in version control and deploy identically.

Ramp-up. Very low — a Laravel engineer is productive in hours, since the package follows framework conventions they already know. The genuine learning curve is the allowlist: understanding why each tag and attribute is present, and being disciplined enough not to widen it to make a rendering bug go away. That discipline, not the package, is what determines whether this integration improves or degrades the security posture. Assign one owner for the sanitization policy and route all allowlist changes through code review.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums