Weave Code
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 Laravel Package

symfony/html-sanitizer

Object-oriented HTML sanitizer for PHP/Symfony. Safely cleans untrusted HTML for DOM insertion with configurable allow/block/drop rules, attribute policies, forced values, and URL controls (HTTPS and scheme/host allowlists). Removes scripts and unsafe behaviors.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Laravel Integration: Seamlessly integrates with Laravel’s dependency injection (DI) container via Symfony’s HtmlSanitizer component, leveraging Laravel’s existing Symfony bridge (e.g., symfony/http-foundation). Aligns with Laravel’s security-first philosophy (e.g., Blade templating, form handling).
  • Modularity: Decouples sanitization logic from business layers, enabling reuse across:
    • User-generated content (e.g., comments, forum posts).
    • CMS integrations (e.g., Spatie Media Library metadata).
    • API responses (e.g., sanitizing HTML in JSON:API payloads).
  • Context-Aware Design: Supports tag-specific sanitization (e.g., <head>, <textarea>), critical for Laravel’s multi-context views (e.g., admin vs. public dashboards).

Integration Feasibility

  • Low Friction: Compatible with Laravel’s composer.json (Symfony components are first-class citizens). Example:
    composer require symfony/html-sanitizer
    
  • Service Provider Pattern: Can be bootstrapped as a Laravel service provider to centralize configurations (e.g., global allowlists for all environments).
  • Blade Directives: Extendable via Blade directives for template-level sanitization:
    Blade::directive('sanitize', function ($expression) {
        return "<?php echo app(Symfony\Component\HtmlSanitizer\HtmlSanitizer::class)->sanitize($expression); ?>";
    });
    
    Usage: @sanitize($userHtml).

Technical Risk

  • PHP Version Dependency: Requires PHP 8.1+ (Laravel 9+). Risk mitigated if using modern Laravel stacks.
  • Performance Overhead: Native HTML5 parser in PHP 8.4+ reduces parsing time, but legacy PHP may see ~10–20% slower sanitization vs. DOMPurify (JS). Benchmark in staging.
  • False Positives/Negatives: Misconfigured allowlists (e.g., allowElement('script')) could reintroduce XSS. Mitigate with:
    • Default-Deny Policy: Start with allowSafeElements() and whitelist only necessary tags.
    • Unit Tests: Validate sanitization outputs against OWASP XSS test cases.
  • Attribute Sanitizer Complexity: Custom AttributeSanitizerInterface implementations may require deep PHP/DOM knowledge. Document edge cases (e.g., data-* attributes).

Key Questions

  1. Security Requirements:
    • Are there regulatory mandates (e.g., PCI DSS, HIPAA) requiring auditable sanitization?
    • Should sanitization logs be immutable (e.g., stored in a WORM system)?
  2. Performance SLAs:
    • What’s the max acceptable latency for sanitizing high-volume inputs (e.g., 10K comments/sec)?
  3. Customization Needs:
    • Are there domain-specific HTML rules (e.g., allowing <math> tags for educational apps)?
  4. Tooling Integration:
    • Should sanitization be enforced in CI (e.g., fail builds if unsafe HTML is detected in PRs)?
  5. Fallback Strategy:
    • What’s the plan for PHP <8.1 environments (e.g., legacy Laravel 8 apps)?

Integration Approach

Stack Fit

  • Laravel Ecosystem: Native compatibility with:
    • Symfony Components: Uses symfony/http-foundation (already in Laravel).
    • Laravel Valet/Sail: Pre-configured PHP 8.4+ environments accelerate testing.
    • Laravel Mix/Vite: Sanitize HTML in build pipelines (e.g., for static assets).
  • Third-Party Packages:
    • Spatie Media Library: Sanitize file metadata (e.g., <title> tags).
    • Laravel Nova: Sanitize rich-text fields in admin panels.
    • CMS Packages (e.g., October CMS): Replace custom sanitization logic.

Migration Path

  1. Phase 1: Pilot Project
    • Scope: Sanitize a single high-risk endpoint (e.g., /api/comments).
    • Implementation:
      • Create a HtmlSanitizerService provider.
      • Replace htmlspecialchars() with sanitize() in Blade templates.
      • Add a middleware to sanitize all user-generated HTML inputs.
    • Validation: Use XSS Game to test edge cases.
  2. Phase 2: Rollout
    • Global Configuration: Centralize allowlists in config/sanitizer.php.
    • Blade Directives: Add @sanitize directive for templates.
    • API Wrappers: Create a Sanitizer facade for business logic.
  3. Phase 3: Optimization
    • Caching: Cache sanitizer configurations for static contexts (e.g., <head>).
    • Async Processing: Offload sanitization for non-critical paths (e.g., email templates).

Compatibility

  • Laravel Versions:
    • Laravel 9+: Full compatibility (PHP 8.1+).
    • Laravel 8: Use Symfony v6.x (PHP 8.0+).
    • Legacy: Requires polyfills or alternative (e.g., HTMLPurifier).
  • Database: No schema changes, but ensure text fields (e.g., body) can store sanitized HTML.
  • Frontend: Works with any frontend (React, Vue, Svelte) via API responses.

Sequencing

  1. Dependency Setup:
    • Add symfony/html-sanitizer to composer.json.
    • Install PHP 8.4+ if using native parser.
  2. Configuration:
    • Define base allowlists in config/sanitizer.php:
      'default' => [
          'allowed_elements' => ['p', 'a', 'b', 'i', 'u', 'em', 'strong'],
          'allowed_attributes' => ['href', 'title', 'class'],
          'force_https' => true,
      ],
      
  3. Service Binding:
    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton(HtmlSanitizer::class, function ($app) {
            $config = (new HtmlSanitizerConfig())
                ->allowSafeElements()
                ->allowElement('a', ['href', 'title']);
            return new HtmlSanitizer($config);
        });
    }
    
  4. Usage:
    • Controllers:
      $sanitizer = app(HtmlSanitizer::class);
      $safeHtml = $sanitizer->sanitize($userInput);
      
    • Blade:
      {!! app('sanitizer')->sanitize($comment->body) !!}
      

Operational Impact

Maintenance

  • Dependency Updates: Leverage Laravel’s Symfony bridge for auto-updates (e.g., composer update symfony/*).
  • Configuration Drift: Version-control config/sanitizer.php to track allowlist changes.
  • Deprecation Risk: Monitor Symfony’s roadmap for breaking changes (e.g., PHP 8.4+ parser).

Support

  • Debugging: Use dd($sanitizer->sanitize($input, debug: true)) to inspect dropped elements.
  • Community: Symfony’s ecosystem provides extensive docs and Stack Overflow support.
  • Custom Rules: Document non-standard allowlists (e.g., allowElement('custom-tag')) in a README.

Scaling

  • Horizontal Scaling: Stateless sanitization works across all app instances.
  • Rate Limiting: Sanitization is CPU-bound; monitor queue workers for high-volume inputs.
  • Edge Cases: Test with:
    • Malformed HTML: <div><p>Unclosed tag.
    • Unicode: 🔗 in URLs or attributes.
    • Large Payloads: 1MB+ HTML strings (benchmark memory usage).

Failure Modes

Failure Impact Mitigation
Misconfigured allowlist XSS vulnerabilities Default-deny policy + code reviews.
PHP 8.4 parser regression Sanitization failures Fallback to MastermindsParser in config.
High CPU load Slow responses Cache configurations; offload to queues.
Custom sanitizer bugs False positives/negatives Unit tests with OWASP XSS payloads.
Dependency conflicts Package installation failures Isolate in a sanitizer namespace.

Ramp-Up

  • Onboarding:
    • Developers: 1-hour workshop on:
      • Configuring allowlists.
      • Debugging dropped elements.
      • Extending AttributeSanitizerInterface.
    • QA: Train on XSS test cases
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport