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

Filter Laravel Package

joomla/filter

Joomla's Filter package provides input and output sanitization utilities, letting you validate and clean user data and build URL-safe strings for secure PHP applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Laravel’s Native Alternatives: Laravel’s built-in e() helper, Illuminate\Validation\Rules\Sanitize, and packages like htmlpurifier/htmlpurifier already address HTML sanitization. This package introduces redundancy unless Joomla-specific filtering rules (e.g., OutputFilter::stringURLSafe) are explicitly required.
  • Security Focus: The package targets XSS mitigation (e.g., stripping javascript:/data: URIs and evasion characters) but lacks Laravel-native features like request validation pipelines or middleware integration. The 3.0.7 release confirms the scope is adversarial input filtering, not general-purpose HTML purification — two bypasses were found and fixed in the URI and entity-decoding paths.
  • Joomla Dependency: Optional Joomla\Language dependency for stringURLSafe creates unnecessary coupling for Laravel apps not using Joomla components.
  • Key Strengths:
    • Configurable tag/attribute whitelisting/blacklisting (e.g., allow <b>, <i> but block <script>).
    • Lightweight (~50KB) with no heavy dependencies (unlike HTMLPurifier).
    • Battle-tested in Joomla (though PHP-centric).
  • Key Weakness (reaffirmed by 3.0.7): The filter is a hand-rolled, regex/parse-based sanitizer. Two bypasses in a single patch release (whitespace-obfuscated data: URIs, HTML5 entity decode mismatch) is the classic signature of this design pattern. HTMLPurifier’s parser-based model exists precisely to avoid this class of bug.

Technical Risk

  • ⚠️ Security Patch Released — 3.0.7 (Action Required): Two XSS filter bypasses were fixed:
    • Bypass via whitespace characters in HTML data: URIs — a data: URI with injected whitespace evaded the scheme check. The prior assessment credited this package with reliably "stripping data: URIs"; that claim is false for versions ≤ 3.0.6.
    • Bypass via HTML5 entity decode mismatch — the filter and the downstream HTML5 parser disagreed on entity decoding, allowing payloads to pass the filter and reconstitute in the browser (classic mutation/decoding-differential XSS).
    • Implication: Any environment on 3.0.6 or earlier is exploitable if user-supplied HTML or URI-bearing attributes reach storage or output. This is a patch-level upgrade with no API change, so remediation cost is near zero — but the finding materially changes the risk narrative.
  • Revised view on CVE history: The prior assessment stated "no recent CVEs suggest improved rigor." The 3.0.7 release contradicts that inference — absence of CVEs reflected undiscovered bypasses, not hardening. Treat the package as actively probed but structurally fragile; assume further bypass classes remain (CSS injection, SVG/MathML foreign content, mutation XSS).
  • Advisory Status Is Unclear: Release notes cite no CVE IDs or GHSA identifiers. Whether 3.0.6 users were formally notified (GitHub Security Advisories, Packagist advisories, composer audit) is unverified and must be confirmed — silent patches are a supply-chain monitoring gap.
  • Low Stars/Dependents (15 stars, 0 dependents): Still signals low adoption and stagnation risk, and lowers the likelihood that bypasses are found by the broader community rather than by the maintainers alone.
  • PHP Version Lock-in:
    • v3.x requires PHP 8.1+ (blocks legacy Laravel apps).
    • v4.x requires PHP 8.3+ (may limit compatibility).
    • 3.0.7 is a v3.x patch, so PHP 8.1/8.2 shops (Laravel 9/10) can remediate without a major upgrade — this is the fastest path.
  • Breaking Changes: v4.0.0+ drops older PHP versions; v3.x renamed constants (e.g., TAGS_WHITELIST → ONLY_ALLOW_DEFINED_TAGS).
  • Testing Gaps: No Laravel-specific tests; integration risks include conflicts with Laravel’s auto-escaping (Blade, e()) causing double-encoding, and unbenchmarked overhead in high-traffic APIs.

Key Questions for TPM

  1. Immediate Remediation (new, highest priority)
    • Which services in the estate depend on joomla/filter ≤ 3.0.6? Is anything pinned to exactly 3.0.6?
    • Do those services accept data: URIs or URI-bearing attributes (href, src, xlink:href) from users — i.e., are they actually exposed to bypass #1?
    • Do they render sanitized content into an HTML5 DOM (browser or DOMDocument), which is the precondition for the entity-decode mismatch bypass?
    • Was there a security advisory for 3.0.6, and did our monitoring catch it? If we learned of this from a routine release-notes review, our advisory pipeline failed.
  2. Why Not Laravel Native?
    • Does the team need Joomla-specific filtering rules (e.g., stringURLSafe), legacy Joomla components, or is the configurable whitelisting the only differentiator?
    • Given two bypasses in one patch, is htmlpurifier/htmlpurifier's slower-but-parser-based model now the better risk trade?
  3. Maintenance Strategy
    • How will the team monitor updates (v4.x PHP 8.3+ requirement, plus patch advisories)?
    • What is the fallback plan if the package stagnates (fork or migrate to HTMLPurifier)?
  4. Performance Impact
    • Will this be used in high-throughput endpoints, and has it been benchmarked against e() / strip_tags()?
  5. Security Tradeoffs
    • Does the package cover the full OWASP XSS vector set — SVG, CSS injection, mutation XSS, and now encoding/whitespace differentials?
    • How does it interact with Laravel’s CSRF protection and CORS policies?
  6. Dependency Risks
    • Will the optional Joomla\Language package introduce bloat or conflicts? Any hidden PHP extension requirements (e.g., mbstring)?

Integration Approach

Stack Fit

  • Laravel Compatibility:
    • Pros: Composer-friendly, PHP 8.1+ aligned with Laravel 9+/10+, and 3.0.7 ships as a drop-in patch with no API change.
    • Cons: No Laravel-specific middleware or validation rules; requires manual wrapping.
  • Recommended Integration Points:
    1. Form Request Validation:
      use Joomla\Filter\InputFilter;
      use Illuminate\Validation\Rule;
      
      public function rules()
      {
          return [
              'comment' => [
                  'required',
                  Rule::custom(function ($attribute, $value, $fail) {
                      $filter = new InputFilter();
                      $filtered = $filter->clean($value, InputFilter::ONLY_ALLOW_DEFINED_TAGS, ['p', 'b', 'i']);
                      // Compare or return filtered value
                  }),
              ],
          ];
      }
      
    2. Middleware for Global Filtering:
      namespace App\Http\Middleware;
      
      use Joomla\Filter\InputFilter;
      use Closure;
      
      class SanitizeInput
      {
          public function handle($request, Closure $next)
          {
              $filter = new InputFilter();
              $request->merge([
                  'input_field' => $filter->clean($request->input_field, InputFilter::ONLY_ALLOW_DEFINED_TAGS, ['a']),
              ]);
              return $next($request);
          }
      }
      
    3. Service Provider for Reusability:
      $this->app->singleton(InputFilter::class, function ($app) {
          return new InputFilter();
      });
      
  • Convention to enforce given the 3.0.7 findings: treat output as untrusted even after filtering. Apply contextual output escaping (e(), Blade {{ }}) at render time and scheme allowlisting on any URI attribute (href/src must match ^https?: or a relative path) rather than relying on the filter alone. The entity-decode mismatch bypass is only neutralized end-to-end if the filter and the renderer agree — an independent scheme/attribute check closes that gap.
  • Alternative Approaches:
    • Wrapper Package: Publish a Laravel-specific facade (e.g., laravel-joomla-filter) to abstract Joomla dependencies and to centralize the compensating URI-scheme check so no team re-implements it.
    • Hybrid Solution: Use this package for Joomla-specific rules and Laravel’s e() for general escaping.

Migration Path

  1. Emergency Patch (new, precede all other steps):
    • Bump joomla/filter to 3.0.7 across every consuming service. Loosen any exact pin on 3.0.6 (e.g., 3.0.6 → ^3.0.7 or ~3.0.7).
    • Run composer update joomla/filter --with-dependencies, then composer audit.
    • Re-run the existing XSS regression payloads plus two new cases: data: URIs with embedded whitespace/tabs/newlines, and payloads relying on named-entity decoding (e.g., &colon;, &Tab;, &NewLine;).
  2. Assessment Phase: Audit all HTML input sources (forms, APIs, CMS plugins). Identify critical XSS risks (user avatars, rich-text fields, any stored href/src).
  3. Pilot Integration: Start with non-critical endpoints (contact forms); compare output with e() and strip_tags().
  4. Gradual Rollout: Replace strip_tags() calls with InputFilter where configurable whitelisting is needed; phase out custom regex-based sanitization.
  5. Fallback Plan: If further bypasses or performance issues surface, migrate to htmlpurifier/htmlpurifier or Laravel native tools. Note the 3.0.7 findings raise the probability of triggering this plan.

Compatibility

  • PHP Version: Target v3.0.7 for PHP 8.1+ (Laravel 9+); v4.x only where PHP 8.3+ (Laravel 11+) is already in place. Do not jump to v4.x purely to obtain this security fix.
  • Laravel Version: Test 3.0.7 against Laravel 9/10 (PHP 8.1/8.2) and Laravel 11 (PHP 8.3+) where v4.x is in use.
  • Dependency Conflicts: Check for conflicts with joomla/language if stringURLSafe is used; avoid pairing with htmlpurifier/htmlpurifier (duplicate sanitization).
  • Version Matrix Update:
    Constraint Status
    3.0.7 (PHP 8.1+) Recommended — includes both XSS fixes
    3.0.6 and below Vulnerable — do not deploy
    4.x (PHP 8.3+) Verify equivalent fixes are present in the 4.x line

Sequencing

  1. Phase 0 (this week): Upgrade all joomla/filter consumers to 3.0.7; confirm composer audit is clean; verify 4.x consumers received the equivalent fix.
  2. Phase 1: Add the package via Composer as ~3.0.7 (never a bare 3.0.6 pin).
  3. Phase 2: Create a custom facade that wraps InputFilter and adds the URI-scheme allowlist.
  4. Phase 3: Integrate into Form Requests for critical inputs.
  5. Phase 4: Add middleware for global filtering (if needed).
  6. Phase 5: Deprecate custom sanitization logic.

Operational Impact

Maintenance

  • Update Strategy:
    • Pin to a specific minor/patch floor (e.g., ^3.0.7) — not an exact 3.0.6. Exact patch pins now have a demonstrated security cost.
    • Monitor Joomla Framework releases for security patches; subscribe to GitHub Security Advisories for joomla-framework/filter and enable composer audit in CI.
  • Patch SLA (new): Classify filter bypasses as P1 — remediation within 72 hours of a patch release for internet-facing services, one sprint for internal tools. The 3.0.7 upgrade is a one-line change, so the SLA is achievable; the risk is detection latency, not effort.
  • Dependency Management: Use composer why-not joomla/filter to check for conflicts. Consider a custom fork if the package stagnates (low effort — small codebase) — but note a fork means we own all future bypass remediation, which 3.0.7 shows is real, recurring work.
  • Documentation: Maintain a runbook covering:
    • The 3.0.7 upgrade and its two payload regression tests.
    • Upgrading between major versions (v3 → v4).
    • Handling Joomla\Language dependency warnings.

Support

  • Issue Tracking: Open GitHub Issues for Laravel-specific bugs (e.g., middleware integration); engage Joomla Framework maintainers for core filtering logic.
  • Incident Response: Add a "sanitizer bypass" playbook — identify affected endpoints, rotate/deactivate stored payloads, add the new payload to the permanent regression corpus, and redeploy with the patched filter.
  • Fallback Support: Document workarounds for unsupported PHP versions (e.g., strip_tags fallback, which is weaker — flag as temporary only). Train devs to test with OWASP XSS payloads, specifically whitespace-obfuscated data: URIs, HTML5 named entities, and mutation-XSS vectors.
  • Vendor Communication: Request that the maintainers publish CVE/GHSA identifiers for future bypasses; without them, downstream users cannot reliably detect exposure.

Scaling

  • Performance: Benchmark against e() and strip_tags() for high-traffic endpoints; cache InputFilter instances via the service container. Any compensating scheme-check added post-3.0.7 should be a cheap regex and not a second full parse.
  • Load Testing: Test with 10K+ requests/sec to identify regex-heavy bottlenecks; consider asynchronous filtering for non-critical paths.
  • Horizontal Scaling: No known stateful dependencies; scales horizontally like Laravel.

Failure Modes

Failure Scenario Trigger Impact Mitigation
XSS bypass — whitespace in data: URI Filter ≤ 3.0.6; user-supplied URI attribute Script execution in victim browsers; stored XSS if persisted Upgrade to 3.0.7; enforce independent ^https?:/relative scheme allowlist
XSS bypass — HTML5 entity decode mismatch Filter ≤ 3.0.6; sanitized HTML rendered by an HTML5 parser Payload reconstitutes post-filter; mutation XSS Upgrade to 3.0.7; contextual output escaping at render; regression-test entity payloads
Undiscovered bypass class SVG/MathML foreign content, CSS injection, further encoding differentials Unknown; potentially stored XSS Assume not fully solved; independent output escaping as defense-in-depth; periodic red-team payload review
Silent advisory / detection lag No CVE/GHSA published; no advisory subscription Extended exposure window well beyond patch availability Subscribe to GitHub Advisories + composer audit in CI; routine release-note review
Major version breakage (v3 → v4) PHP 8.3 requirement; renamed constants Build failures, refactor cost Stay on 3.0.7; stage v4 with full test suite
Over-escaping / double encoding Filter output re-escaped by Blade {{ }} Corrupted output (e.g., &amp;amp;), broken links Decide escape-at-input vs escape-at-output per layer; document the contract
Misconfigured whitelist Overly permissive tag/attribute list Allows unsafe attributes (on*, style) Restrictive defaults; config review in code review
Package abandonment Maintainer inactivity at 15 stars No future security patches Maintain fork only with explicit ownership of CVE response; else migrate to HTMLPurifier
Joomla\Language resolution failure Optional dependency omitted but stringURLSafe called Runtime exception Guard the call path; avoid stringURLSafe in Laravel-only services
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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table