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

Purify Laravel Package

stevebauman/purify

Laravel wrapper for HTMLPurifier to sanitize user-submitted HTML and prevent XSS. Clean strings or arrays via the Purify facade, with support for per-call (dynamic) configuration and published config for app-wide rules.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require stevebauman/purify
    php artisan vendor:publish --provider="Stevebauman\Purify\PurifyServiceProvider"
    
    • This installs the package and publishes the default config/purify.php.
  2. First Use Case:

    • Clean a user-submitted string:
      use Stevebauman\Purify\Facades\Purify;
      
      $cleaned = Purify::clean('<script>alert("XSS")</script><p>Hello</p>');
      // Returns: '<p>Hello</p>'
      

Where to Look First

  • Configuration: Review config/purify.php for default settings and available configs (e.g., default, comments).
  • Facade: Use Purify::clean() for basic sanitization.
  • Caching: Check serializer settings in the config for performance tuning.

Implementation Patterns

Core Workflows

  1. Sanitizing User Input:

    • Form Handling: Clean input before saving to the database:
      $title = Purify::clean(request('title'));
      
    • API Requests: Sanitize JSON payloads:
      $data = Purify::clean(json_decode(request()->getContent(), true));
      
  2. Dynamic Configurations:

    • Override defaults for specific use cases (e.g., rich-text editors):
      $cleaned = Purify::config(['HTML.Allowed' => 'div,p,a[href]'])->clean($input);
      
    • Use named configs (e.g., comments):
      $cleaned = Purify::config('comments')->clean(request('content'));
      
  3. Eloquent Integration:

    • Sanitize on Retrieval (recommended for security):
      use Stevebauman\Purify\Casts\PurifyHtmlOnGet;
      
      class Post extends Model {
          protected $casts = ['content' => PurifyHtmlOnGet::class];
      }
      
    • Sanitize on Storage (less common):
      use Stevebauman\Purify\Casts\PurifyHtmlOnSet;
      protected $casts = ['content' => PurifyHtmlOnSet::class];
      
  4. Batch Processing:

    • Clean arrays of input (e.g., bulk imports):
      $cleanedArray = Purify::clean([
          '<script>alert("XSS")</script>',
          '<b>Safe</b>'
      ]);
      

Integration Tips

  • Middleware: Create middleware to auto-sanitize request data:
    public function handle($request, Closure $next) {
        $request->merge(array_map([Purify::class, 'clean'], $request->all()));
        return $next($request);
    }
    
  • Service Layer: Encapsulate sanitization logic in a service:
    class ContentService {
        public function sanitize($content, $config = 'default') {
            return Purify::config($config)->clean($content);
        }
    }
    
  • Validation Rules: Combine with Laravel validation:
    $validator = Validator::make($request->all(), [
        'content' => 'required|string|purify', // Custom rule
    ]);
    

Gotchas and Tips

Pitfalls

  1. Caching Quirks:

    • Cache Invalidation: Forgetting to run php artisan purify:clear after updating definitions or configs causes stale purifier rules.
    • Filesystem Permissions: Ensure the serializer path (e.g., storage/app/purify) is writable by the web server.
    • Cache Driver: Using Cache::clear() on the default cache driver may unintentionally clear other cached data. Use a dedicated cache store for Purify.
  2. Performance:

    • Disabled Caching: Setting serializer: null in production causes repeated serialization, degrading performance.
    • Large Definitions: Complex custom definitions (e.g., for WYSIWYG editors) increase memory usage and processing time.
  3. Configuration Overrides:

    • Non-Merged Configs: Dynamic configs passed to Purify::config() replace defaults, not merge with them. Use array_merge if needed:
      $config = array_merge(config('purify.configs.default'), ['HTML.Allowed' => '...']);
      Purify::config($config)->clean($input);
      
  4. HTMLPurifier Limitations:

    • Unsupported Elements: Custom elements/attributes not defined in HTML.Doctype (e.g., HTML5) will be stripped. Extend definitions via Html5Definition or custom classes.
    • CSS Properties: Missing CSS values (e.g., text-align: start) require custom CssDefinition classes.

Debugging Tips

  1. Log Purified Output:
    • Compare input/output to identify stripped content:
      \Log::debug('Purified:', ['input' => $dirty, 'output' => $cleaned]);
      
  2. Validate Definitions:
    • Test custom definitions with a minimal example:
      $testInput = '<custom-tag attr="value">Content</custom-tag>';
      $cleaned = Purify::clean($testInput);
      
  3. Check Serializer Path:
    • Verify the cache directory exists and is writable:
      ls -la storage/app/purify
      
  4. HTMLPurifier Errors:
    • Enable HTMLPurifier’s debug mode in config:
      'Core.DebugInfo' => true,
      
    • Check Laravel logs for HTMLPurifier_Exception traces.

Extension Points

  1. Custom Definitions:
    • HTML Elements: Extend Html5Definition for unsupported tags (e.g., Trix editor):
      class TrixDefinition implements Definition {
          public static function apply($definition) {
              Html5Definition::apply($definition);
              $definition->addElement('figure', 'Inline', 'Flow', 'Common');
              // Add attributes...
          }
      }
      
    • CSS Properties: Override default CSS rules:
      class CustomCssDefinition implements CssDefinition {
          public static function apply($definition) {
              $definition->info['text-align'] = new \HTMLPurifier_AttrDef_Enum(
                  ['start', 'end', 'left', 'right']
              );
          }
      }
      
  2. Dynamic Config Loading:
    • Load configs from a database or API:
      $dynamicConfig = DB::table('purify_configs')->where('name', 'editor')->first();
      Purify::config(json_decode($dynamicConfig->settings, true))->clean($input);
      
  3. Event Listeners:
    • Trigger events before/after purification:
      Purify::extend(function ($purifier) {
          $purifier->addListener('preClean', function ($input) {
              // Pre-process input
          });
      });
      
  4. Testing:
    • Mock the facade for unit tests:
      Purify::shouldReceive('clean')->once()->andReturn('<p>Mocked</p>');
      
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