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

MIT-licensed PHP 7.3+ DOM/SVG/MathML sanitizer using DOMDocument and DOMPurify-based allowlists. Remove dangerous tags/attributes, strip namespaces and PHP/HTML/XML tags, and optionally compress output. Supports HTML, SVG, and MathML modes.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require rhukster/dom-sanitizer
    

    Add to composer.json under require:

    "rhukster/dom-sanitizer": "^1.0.11"
    
  2. Basic Usage (HTML):

    use Rhukster\DomSanitizer\DOMSanitizer;
    
    $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
    $cleanHtml = $sanitizer->sanitize($untrustedHtml);
    
  3. Basic Usage (SVG):

    $sanitizer = new DOMSanitizer(DOMSanitizer::SVG);
    $cleanSvg = $sanitizer->sanitize($untrustedSvg);
    

First Use Case

Sanitize user-uploaded SVG files in a Laravel app (e.g., profile avatars or diagrams):

use Rhukster\DomSanitizer\DOMSanitizer;

public function storeAvatar(Request $request)
{
    $request->validate(['avatar' => 'required|file|mimes:svg']);

    $svgContent = file_get_contents($request->file('avatar')->getRealPath());
    $sanitizer = new DOMSanitizer(DOMSanitizer::SVG);
    $cleanSvg = $sanitizer->sanitize($svgContent);

    // Save $cleanSvg to storage...
}

Where to Look First

  • README.md: For quickstart examples and option defaults.
  • Release Notes (1.0.11): Security hardening details (XXE protections).
  • DOMSanitizer Class: Methods like addAllowedTags() for customization.

Implementation Patterns

Core Workflows

  1. Sanitizing Dynamic Content:

    // Laravel Blade example: Sanitize user comments
    $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
    $safeComment = $sanitizer->sanitize($userInput, [
        'remove-php-tags' => true,
        'compress-output' => false,
    ]);
    
  2. SVG-Specific Processing:

    // Whitelist custom SVG attributes (e.g., for a diagram tool)
    $sanitizer = new DOMSanitizer(DOMSanitizer::SVG);
    $sanitizer->addAllowedAttributes(['data-custom-id', 'data-layer']);
    $cleanSvg = $sanitizer->sanitize($svgInput);
    
  3. MathML Integration:

    // Sanitize MathML for a LaTeX-to-MathML converter
    $sanitizer = new DOMSanitizer(DOMSanitizer::MATHML);
    $safeMathml = $sanitizer->sanitize($mathmlInput, [
        'remove-namespaces' => true,
    ]);
    

Laravel Integration Tips

  1. Service Provider Binding:

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton(DOMSanitizer::class, function ($app) {
            return new DOMSanitizer(DOMSanitizer::HTML);
        });
    }
    
  2. Request Filter Middleware:

    // app/Http/Middleware/SanitizeInput.php
    public function handle($request, Closure $next)
    {
        $sanitizer = app(DOMSanitizer::class);
        $request->merge([
            'clean_content' => $sanitizer->sanitize($request->input('content')),
        ]);
        return $next($request);
    }
    
  3. Form Request Validation:

    // app/Http/Requests/SanitizeSvgRequest.php
    public function sanitizeSvg($svg)
    {
        $sanitizer = new DOMSanitizer(DOMSanitizer::SVG);
        return $sanitizer->sanitize($svg);
    }
    
  4. Event Listeners:

    // Sanitize model attributes before saving
    public function saving($model)
    {
        if ($model->isDirty('svg_content')) {
            $sanitizer = new DOMSanitizer(DOMSanitizer::SVG);
            $model->svg_content = $sanitizer->sanitize($model->svg_content);
        }
    }
    

Performance Patterns

  • Reuse Instances: Create a single DOMSanitizer instance for repeated use (e.g., in a service container).
  • Disable Compression: Set 'compress-output' => false if you need to inspect the sanitized output for debugging.
  • Batch Processing: For large volumes, process in chunks and cache sanitized results (e.g., Redis).

Gotchas and Tips

Pitfalls

  1. XXE Risks in Legacy Code:

    • If using loadXML() or simplexml_load_string() elsewhere, ensure they also use LIBXML_NONET and disable entity loading:
      libxml_disable_entity_loader(true);
      $dom = new DOMDocument();
      $dom->loadXML($input, LIBXML_NONET);
      
    • Fix: Replace all custom XML parsing with DOMSanitizer::sanitize().
  2. False Positives in SVG:

    • SVG filters (e.g., feGaussianBlur) were incorrectly removed in v1.0.9. Ensure you’re on ^1.0.10 or later.
    • Debug: Check getAllowedTags() to verify filters are included.
  3. CSS Injection in <style>:

    • Even with DOMSanitizer::SVG, <style> tags are stripped by default. If you need styles, whitelist them carefully:
      $sanitizer->addAllowedTags(['style']);
      $sanitizer->addAllowedAttributes(['style' => ['type']]);
      
    • Tip: Use addDisallowedAttributes(['style' => ['url']]) to block external CSS URLs.
  4. Entity Encoding Bypasses:

    • Attackers may use ASCII whitespace entities (e.g., &#x09;) to smuggle javascript: URIs. The package fixes this in ^1.0.10, but test edge cases:
      // Test case: Ensure this fails
      $malicious = '<a href="&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3A;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x78;&#x29;">Click</a>';
      $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
      $result = $sanitizer->sanitize($malicious); // Should strip the href
      
  5. Namespace Handling:

    • SVG/MathML namespaces (e.g., xmlns="http://www.w3.org/2000/svg") are preserved by default. To remove them:
      $sanitizer = new DOMSanitizer(DOMSanitizer::SVG, [
          'remove-namespaces' => true,
      ]);
      

Debugging Tips

  1. Inspect Allowed/Disallowed Lists:

    $sanitizer = new DOMSanitizer(DOMSanitizer::SVG);
    dump($sanitizer->getAllowedTags());      // View whitelisted tags
    dump($sanitizer->getDisallowedAttributes()); // View blocked attributes
    
  2. Log Sanitization Steps:

    $sanitizer = new DOMSanitizer(DOMSanitizer::HTML);
    $sanitizer->setLogger(function ($message) {
        \Log::debug('DOMSanitizer', ['message' => $message]);
    });
    
  3. Test Edge Cases:

    • Billion Laughs: Ensure recursive entities are blocked.
      $input = <<<'XML'
      <!DOCTYPE foo [
        <!ENTITY a "aaaa">
        <!ENTITY b "&a;&a;&a;&a;">
      ]>
      <svg>&b;</svg>
      XML;
      $sanitizer = new DOMSanitizer(DOMSanitizer::SVG);
      $result = $sanitizer->sanitize($input); // Should return empty or safe SVG
      
    • External Entities: Test file:// and http:// references.
      $input = '<svg><script xlink:href="file:///etc/passwd"/></svg>';
      $result = $sanitizer->sanitize($input); // Should strip the script
      

Extension Points

  1. Custom Allowlists:
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony