smorken/sanitizer
Sanitizer for Laravel and PHP applications that cleans untrusted input and output, stripping unsafe HTML and helping prevent XSS. Configurable filters make it easy to define allowed tags and attributes for safe, consistent data handling.
Architecture fit. smorken/sanitizer presents itself as a thin "sanitizer helper" — most likely a Laravel service provider plus a facade and/or a global sanitize() helper that wraps an underlying HTML sanitization engine (almost certainly ezyang/htmlpurifier, and if not, something hand-rolled, which is far worse). Architecturally that means low coupling and trivial adoption surface, but also near-zero differentiation: Laravel already gives us validation rules, Blade escaping, and strip_tags, and the de facto community package for this job is mews/purifier, which is a maintained wrapper around the same underlying engine. A thin, unmaintained wrapper around a security-critical library is the worst of both worlds — we inherit the dependency's CVE exposure without inheriting its maintenance cadence.
Integration feasibility. The package is not evidently distributed via Packagist (zero dependents, no discoverable version metadata), so consumption requires a Composer vcs repository entry pointing at Bitbucket. That pulls Bitbucket authentication into every developer machine and CI runner — and Atlassian has been retiring app passwords in favor of scoped API tokens, so our credential story becomes a standing operational liability for what is, at most, a few hundred lines of glue code. Composer 2 also requires a valid name in the package's own composer.json for VCS installs, and without tagged releases we'd be pinning branches or commit SHAs and carrying minimum-stability/prefer-stable friction into the root project. None of this is disqualifying, but it is disproportionate ceremony for the functionality.
Technical risk. This is the dominant concern. Sanitization is a security boundary, and the signals here — no stars, no dependents, no visible release history, a personal Bitbucket namespace, no stated license, no security disclosure path — are consistent with an abandoned personal utility. Specific unknowns that materially change the risk profile:
strip_tags-based implementation is a false sense of security and must not ship.href, CSS, and JS contexts. A single global sanitize($string) helper invites misuse in the wrong context.HTML.Allowed with style, target, custom URIs) reintroduce mutation-XSS and javascript: vector risk.illuminate/support constraint would make this a non-starter regardless of code quality.Key questions for the maintainer (or our own source audit):
Recommendation: treat this as read-for-reference, not adopt-as-dependency. Budget roughly a half-day to audit the source; if it is a competent HTMLPurifier wrapper, replicate the ~200 lines internally behind our own interface. The build cost is lower than the ongoing cost of vendoring an unmaintained third-party security dependency through a non-Packagist channel.
Stack fit. Assuming Lumen/Laravel 9+, the package would register via package discovery with a provider and optional facade alias. Fit is contingent on three checks before any code is written: (a) composer.json requires a laravel/framework / illuminate/support range that includes our pinned version, (b) it declares ext-dom and ext-libxml (HTMLPurifier's requirements) so our base images are validated at build time, and (c) it does not register a global helper that collides with an existing sanitize() in our codebase — the most common silent-breakage mode for helper packages.
Migration path. Do not let the package's API leak into application code. Define an internal contract — App\Contracts\HtmlSanitizer with methods that name the context (cleanHtml(), cleanAttribute(), cleanUrl()) rather than the mechanism — and bind the implementation in a service provider. If we adopt the package, one adapter class wraps its facade; if we replace it with mews/purifier or a direct HTMLPurifier integration, only that adapter changes. This is the single highest-leverage decision in the whole assessment and costs about an hour.
Compatibility and sequencing.
composer.lock; add the fork to our dependency-review allowlist.data: URIs, mutation XSS, deeply nested input), plus over-sanitization cases (tables, iframe embeds, style attributes) so we detect content-corruption regressions before users do.strip_tags/htmlspecialchars on user-supplied rich content, so new code routes through the contract.Compatibility landmines to verify explicitly: PHP 8.1+ deprecation noise from older HTMLPurifier versions; facade alias registration conflicting with an existing alias; config caching (php artisan config:cache) when the package reads config at boot; and autoload files entries that only load helpers after the framework boots.
Maintenance. Assume we own it from day one. With zero stars, zero dependents, and no release history, the probability of upstream maintenance is low enough that planning for it is the only responsible posture. The mitigation is cheap — a fork with a CI pipeline is a sub-day task — but it must be scheduled, not discovered. The real maintenance burden is not this package; it is the transitive obligation to track HTMLPurifier advisories ourselves, since an unmaintained wrapper will never bump the underlying engine on our behalf.
Support. There is no support channel we can escalate through: no issue tracker activity expected, no maintainer SLA, no disclosed security contact. Internalize that when this package breaks, the answer is "we fix it," and staff the on-call rota accordingly. For a security-boundary component, that is an acceptable trade only because the code volume is small.
Scaling. HTMLPurifier is CPU-bound and not cheap — typically single-digit to low-double-digit milliseconds per document depending on HTML.Allowed breadth and cache settings. On a write path or a synchronous render path under meaningful throughput, this becomes a hot spot before the database does. Mitigations: keep the allowed-tag set as narrow as the feature permits (permissive configs are both a security and a latency cost), enable HTMLPurifier's definition cache with a warm, filesystem-backed path in the container, sanitize once on write to a trusted-column rather than on every read, and offload sanitization of large or bulk-imported payloads to a queue with a size cap.
Failure modes to instrument.
files ordering or a facade alias miss producing a fatal in production only. Detect with a smoke test that exercises the sanitizer post-config:cache.composer install in CI. Eliminated entirely by forking internally.Ramp-up. API learn time is negligible (minutes) — the package is a helper. The genuine ramp-up is the sanitization policy, which this package does not document: which contexts exist, what each permits, and why. Budget a half-day of senior engineering review to write that policy down as part of the migration; it is the artifact that makes the dependency swappable, makes code review tractable, and makes the eventual replacement a mechanical exercise rather than an archaeology project. Do not let a one-line helper function become the de facto, undocumented policy of record for what user HTML our product accepts.
How can I help you explore Laravel packages today?