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

Dom Sanitizer Laravel Package

rhukster/dom-sanitizer

PHP 7.3+ DOM/SVG/MathML sanitizer using DOMDocument and DOMPurify-based allowlists. Removes dangerous tags/attributes, with options for namespace/PHP/HTML/XML stripping and output compression. Customize allowed/disallowed tags and attributes.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:
    composer require rhukster/dom-sanitizer
    
  2. Basic HTML Sanitization:
    use Rhukster\DomSanitizer\DOMSanitizer;
    
    $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
    $cleanHtml = $sanitizer->sanitize($userInput);
    
  3. SVG/MathML Support:
    // For SVG
    $svgSanitizer = new DOMSanitizer(DOMSanitizer::SVG);
    $cleanSvg = $svgSanitizer->sanitize($svgString);
    
    // For MathML
    $mathSanitizer = new DOMSanitizer(DOMSanitizer::MATHML);
    $cleanMath = $mathSanitizer->sanitize($mathmlString);
    

First Use Case

Sanitizing User-Generated Content in a Laravel Form

// In a Controller
public function store(Request $request)
{
    $sanitizer = app(DOMSanitizer::class); // Resolve from container
    $cleanContent = $sanitizer->sanitize($request->input('description'));

    // Store sanitized content
    Post::create([
        'title' => $request->title,
        'content' => $cleanContent,
    ]);

    return redirect()->route('posts.index');
}

Where to Look First

  • README.md: Quickstart examples for HTML/SVG/MathML.
  • Release Notes (1.0.9): Critical security fixes (e.g., SVG bypasses, event handler stripping).
  • DOMSanitizer Class: Methods like addAllowedTags() for customization.

Implementation Patterns

Core Workflows

1. Request Sanitization (API/Middleware)

// Laravel Middleware
public function handle($request, Closure $next)
{
    $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
    $request->merge([
        'sanitized_content' => $sanitizer->sanitize($request->content),
    ]);
    return $next($request);
}

2. Model Observing (Automatic Sanitization)

// AppServiceProvider
public function boot()
{
    Post::observe(PostObserver::class);
}

// PostObserver
public function saving(Post $post)
{
    $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
    $post->content = $sanitizer->sanitize($post->content);
}

3. Blade Template Safety

// Blade template
{!! $sanitizer->sanitize($userComment) !!}

Integration Tips

  • Laravel Service Container: Bind the sanitizer in AppServiceProvider for dependency injection:

    $this->app->singleton(DOMSanitizer::class, function () {
        return new DOMSanitizer(DOMSanitizer::HTML);
    });
    
  • Custom Config: Store allowed tags in config/sanitizer.php:

    return [
        'allowed_tags' => ['p', 'b', 'i', 'a[href]'],
        'disallowed_attributes' => ['style', 'onclick'],
    ];
    

    Then apply in a service:

    $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
    $sanitizer->setAllowedTags(config('sanitizer.allowed_tags'));
    
  • SVG-Specific Features: Whitelist SVG filters for design tools:

    $svgSanitizer = new DOMSanitizer(DOMSanitizer::SVG);
    $svgSanitizer->addAllowedTags(['feGaussianBlur', 'feColorMatrix']);
    
  • MathML for Equations: Disable compression for readability:

    $mathSanitizer = new DOMSanitizer(DOMSanitizer::MATHML, [
        'compress-output' => false,
    ]);
    

Performance Optimization

  • Reuse Instances: Instantiate DOMSanitizer once (e.g., as a singleton) and reuse across requests.
  • Cache Configurations: Pre-configure allowed tags/attributes if used consistently (e.g., for forums vs. SVGs).

Gotchas and Tips

Pitfalls

  1. False Positives with Custom Rules:

    • Overly restrictive disallowed_tags may strip valid content (e.g., <script> in MathML contexts).
    • Fix: Test edge cases with getAllowedTags()/getDisallowedTags() methods.
  2. SVG Filter Case Sensitivity:

    • Tags like <feGaussianBlur> must match the allowlist exactly (camelCase vs. lowercase).
    • Fix: Use addAllowedTags() with correct casing or normalize tags.
  3. Entity Encoding Bypasses:

    • Malicious input like javascript:&#x09;alert(1) may bypass regex checks.
    • Fix: Always use the latest version (1.0.9+ includes DOM-level URL validation).
  4. Compression Artifacts:

    • compress-output: true may break SVG/MathML structure.
    • Fix: Disable compression for non-HTML content:
      $sanitizer->sanitize($svg, ['compress-output' => false]);
      
  5. PHP Extensions:

    • Requires dom and libxml extensions (enabled by default in Laravel).

Debugging Tips

  • Inspect Sanitized Output:

    $sanitizer->sanitize($input, ['debug' => true]); // Hypothetical; use DOM methods if needed.
    
    • Workaround: Log the DOM tree before/after sanitization:
      $dom = new DOMDocument();
      $dom->loadHTML($input);
      $xpath = new DOMXPath($dom);
      // Inspect nodes with $xpath->query('//*');
      
  • Validate Allowlists: Compare your custom rules against DOMPurify’s defaults:

    $sanitizer->getAllowedTags(); // Check against https://github.com/cure53/DOMPurify
    
  • Event Handler Leaks: If onclick attributes persist, ensure:

    • The DOMSanitizer instance is fresh (reused instances may cache rules).
    • No custom addAllowedAttributes() overrides default behavior.

Extension Points

  1. Dynamic Allowlists: Load tags from a database or config:

    $allowedTags = config('sanitizer.tags.forum');
    $sanitizer->setAllowedTags($allowedTags);
    
  2. Pre/Post-Processing: Chain with Laravel’s Str::of() or HtmlString:

    use Illuminate\Support\HtmlString;
    $clean = new HtmlString($sanitizer->sanitize($input));
    
  3. Custom Sanitizer Class: Extend DOMSanitizer for project-specific logic:

    class AppSanitizer extends DOMSanitizer {
        public function __construct() {
            parent::__construct(DOMSanitizer::HTML);
            $this->addAllowedTags(['custom-tag']);
        }
    }
    
  4. Testing: Use PHPUnit to verify sanitization:

    public function testSanitizesScriptTags()
    {
        $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
        $this->assertStringNotContainsString('<script>', $sanitizer->sanitize('<script>alert(1)</script>'));
    }
    

Configuration Quirks

  • Default Behavior:

    • remove-html-tags: true strips all HTML tags unless overridden.
    • remove-php-tags: true removes <?php ?> blocks (useful for security).
  • Namespace Handling:

    • remove-namespaces: false by default; set to true to strip XML namespaces (e.g., <svg xmlns="...">).
  • Output Formatting:

    • compress-output: true minifies whitespace but may break SVG/MathML. Disable for structured content.

Security Hardening

  1. Block JavaScript URIs: Explicitly disallow javascript: in attributes:

    $sanitizer->addDisallowedAttributes(['href[javascript:]']);
    
  2. SVG-Specific Protections: Restrict SVG to a sandboxed subset:

    $svgSanitizer = new DOMSanitizer(DOMSanitizer::SVG);
    $svgSanitizer->addDisallowedTags(['script', 'animate']);
    
  3. MathML Safety: Whitelist only essential MathML tags:

    $mathSanitizer = new DOMSanitizer(DOMSanitizer::MATHML);
    $mathSanitizer
    
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