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

Security Laravel Package

graham-campbell/security

A Laravel package from Graham Campbell that helps harden your app by adding configurable security headers to HTTP responses. It provides a simple middleware-based setup for common browser protections, making it easy to improve response security with minimal configuration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is a boundary utility, not a security layer. Its product surface is essentially two verbs — clean untrusted HTML, and escape a string — exposed via a facade, a handful of global helpers (security_clean, security_clean_array, security_clean_recursive), and a publishable config. It has no schema footprint, no request-lifecycle coupling, no event wiring, and no middleware of its own. That low blast radius is the single strongest architectural argument in its favour: adoption is cheap and reversal is a Composer revert.

It fits where untrusted HTML must survive rendering — CMS/WYSIWYG fields, comment bodies, profile bios, imported content, templated email. It is irrelevant-to-harmful where Blade's {{ }} already escapes plain output. That distinction matters: putting this package where it isn't needed manufactures false confidence, which is a worse outcome than not adopting it.

Note the package is really two products: a very thin Laravel wrapper (zero listed dependents, composite score 0.3, single maintainer) and the actual sanitiser — voku/anti-xss — which is where all the security behaviour and most of the risk live. Evaluate the transitive dependency, not the wrapper.

Integration feasibility. High on paper: composer require, Laravel auto-discovery, optional config publish, facade plus global helpers, and a documented framework-agnostic path for plain PHP. v11.2.0 explicitly adds Laravel 11 support. The genuine unknowns are constraint shape (does the 11.x line narrow to ^11.0 and drop Laravel 9/10?), whether CI actually runs against Laravel 11 or merely permits installation, and whether the global helpers are autoloaded via files (minor collision/governance surface). The helpers themselves are a double-edged integration story: "one-line call anywhere" is precisely how a sanitiser gets sprayed across a codebase instead of confined to a single boundary.

Technical risk. Moderate, and it is security-programme risk rather than code risk. voku/anti-xss is believed to be a predominantly regex/blacklist-driven filter — confirm this. Blacklist-style HTML filtering is historically the weakest link in XSS defence, so a wrapper that makes it one line away actively encourages teams to believe XSS is "solved." The controls that actually carry the load remain contextual output encoding, a Content-Security-Policy, and framework protections. Secondary risks: semantic ambiguity between clean and escape (is escape meaningfully different from e()?), undocumented fidelity to upstream behaviour, config drift after upgrades, and a one-line changelog that is not evidence of a full test matrix.

Evidence-quality caveat. Zero dependents and a 0.3 score are more consistent with sparse telemetry for a small utility by a long-standing Laravel ecosystem contributor than with a bad package. Don't cite adoption as an argument for or against — run a spike.

Key questions to close before committing:

  1. Which upstream sanitiser (confirm voku/anti-xss) and is it actively patched for published bypass CVEs?
  2. Is clean allowlist-based and per-field configurable, or a global fixed policy? Can policy differ between a comment body and an admin CMS field?
  3. Does escape differ semantically from Laravel's e() / Blade {{ }}? If not, that half of the API is redundant and should not be promoted internally.
  4. Exact php and illuminate/* constraints in composer.json; does the 11.x line drop Laravel 9/10?
  5. Does CI exercise Laravel 11, or only allow it?
  6. Is there a security policy and a documented disclosure/response history? What is the bus factor?
  7. Is there an input-size cap or recursion depth limit on the array/recursive helpers?

Integration Approach

Stack fit. Laravel 11 / PHP 8.2+, and at least one HTML-bearing untrusted input in the product. If the honest answer to "which field needs this?" is "none," the correct decision is no-adopt — record it as a decision, not as an unfinished task. The framework-agnostic path means the decision doesn't strand you if you ever leave Laravel.

Migration path (TPM-owned, bounded spike then rollout):

  1. Spike — 1–2 engineer-days, one engineer. Install in a scratch branch, publish and read the config, and prove it on one real field. Deliverable is a one-page verdict: does it sanitise as advertised, what does it do to legitimate markup (links, tables, emoji, RTL and non-Latin scripts, embedded media), and does it break existing stored content? If the surface is security-critical, benchmark it against mews/purifier and symfony/html-sanitizer in the same spike — the comparison is cheap and strengthens the record either way.
  2. Decide placement — write-time vs read-time. This is a product decision, not a technical one. Write-time sanitisation makes stored content lossy and irreversible; read-time lets you change policy later at CPU cost. Default recommendation: sanitise on write into a separate cleaned column, retain the raw original for audit and repair, render escaped.
  3. Codify the seam. One internal helper, validation rule, or cast that wraps the facade. Ban ad-hoc Security::clean calls by convention plus a static-analysis or code-review rule. This single call site is the entire swap story if the package is later abandoned — treat it as the deliverable, not an afterthought.
  4. Roll out per surface, lowest-risk user-facing content first, with a diff-based content-regression check proving legitimate markup survives.

Compatibility. Verify: PHP 8.2+, Laravel 11, constraint shape on illuminate/*, and clean composer update --dry-run resolution against your other pinned Laravel packages. Confirm the package works through Laravel 11's slim skeleton (bootstrap/app.php + auto-discovery) rather than assuming a legacy config/app.php provider registration.

Sequencing. If you are mid-migration to Laravel 11, land the framework upgrade first — this is a leaf dependency and must never become the critical path. If already on L11, ride the next dependency-refresh window. Do not bundle a security-library change into a feature release; you want a clean rollback boundary.

Effort. 2–4 engineer-days for spike plus a single-surface rollout, plus QA time for content-regression checking. Multiply by distinct HTML surfaces if adopting broadly — at which point the build-vs-standardise conversation with mews/purifier becomes the better use of the same days.

Operational Impact

Maintenance. The wrapper's version line tracks Laravel's major line, so budget a recurring ticket around each framework release. Pin to a caret range and read any major bump as framework coupling, not as a package-API signal. You are watching two release cadences — wrapper and upstream sanitiser — and re-diffing published config on every bump, because a stale config silently shadowing new upstream defaults is a quiet security regression.

Support and bus factor. Effectively single-maintainer. That is acceptable for a leaf utility invoked from one internal helper; it is not acceptable as the sole XSS control for a regulated or high-traffic product. Make the dependency-depth decision explicit in the risk register, name a pre-vetted fallback (mews/purifier or symfony/html-sanitizer), and prove the swap cost is one file.

Scaling. Runtime cost is CPU-bound string processing. Negligible for form input; non-trivial for bulk imports, large CMS payloads, or high-volume API ingestion on the request path. If volume matters, sanitise on a queue and store the result. Impose an input-size cap so pathological payloads can't become a cheap DoS.

Failure modes to plan for:

  • False confidence — highest impact, and organisational, not technical. Teams stop reviewing output encoding because "the security package handles it." Mitigate with a written scope statement and a CSP that does not assume sanitisation succeeded.
  • Content destruction. Over-aggressive filtering silently mangles legitimate content and surfaces as support tickets, not errors. Requires the content-regression check before rollout.
  • Bypass. Any single sanitiser can be defeated; this buys marginal safety at one boundary, not immunity.
  • Config drift after upgrades (see above).
  • Constraint lockout. A narrowed ^11.0 range blocks a future framework upgrade until the maintainer ships. Check the constraint at adoption time, not at upgrade time.
  • Rollback asymmetry. Reverting the package is cheap; deciding what to do with content already written to cleaned columns is not. Design raw-retention up front.

Ramp-up. Technically near-zero — the API is two methods and any Laravel developer is productive in an hour. The real ramp-up is conceptual: the team must internalise escaping ≠ sanitisation, and know which applies at which boundary. Budget a short internal write-up shipped alongside the spike; without it the package gets used inconsistently and the security benefit is illusory.

How to frame the decision. Ask "do we adopt a maintained, low-cost sanitiser for our one HTML surface, with CSP and output encoding remaining the primary controls?" — not "do we improve our security posture by adding this package." Success measures: a documented spike verdict, one sanitised surface with zero content-loss regressions, exactly one call site, a named fallback, and a CSP in place. If those five exist, the low adoption numbers stop being the deciding factor.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource