Symfony HtmlSanitizer Component

repository·8.2·Indexed 42 days ago

https://github.com/symfony/html-sanitizer

An object-oriented API for sanitizing untrusted HTML input to prevent XSS and CSS injection. It features a fluent configuration interface via HtmlSanitizerConfig to allow, block, or drop elements and attributes, and provides context-aware sanitization for the body, head, title, and textarea tags.

Tokens
1.2K
Snippets
2
Records
3
Agent score
5%

What's inside Symfony HtmlSanitizer

  1. Overview of the HtmlSanitizer Component

    8.2
    The HtmlSanitizer component provides an object-oriented API designed to sanitize untrusted HTML input. This ensures that the resulting HTML is safe for insertion into a document's DOM, preventing common security vulnerabilities like XSS or CSS injection.
  2. Configure HTML sanitization with HtmlSanitizerConfig

    8.2

    To use the sanitizer, you first create an HtmlSanitizerConfig object to define your security policy. The configuration uses a fluent interface to allow, block, or drop elements and attributes.

    Key Configuration Concepts:

    • Default Behavior: By default, any element not explicitly allowed or blocked is dropped, including its children.
    • Element Management:
      • allowSafeElements(): Allows a predefined set of 'safe' elements and attributes (removes scripts and dangerous CSS).
      • allowStaticElements(): Allows all static elements/attributes from the W3C Sanitizer API standard.
      • allowElement(string $name, array|string $attributes): Allows a specific element. Use '*' to allow all attributes from the Sanitizer API.
      • blockElement(string $name): Removes the element but retains its children.
      • dropElement(string $name): Removes the element and drops its children.
    • Attribute Management:
      • allowAttribute(string $name, array|string $targets): Allows an attribute on specific elements or globally using '*'.
      • dropAttribute(string $name, array|string $targets): Removes a specific attribute.
      • forceAttribute(string $element, string $attribute, string $value): Forces a specific value on an attribute (e.g., forcing rel="noopener noreferrer" on <a> tags).
    • Link and Media Security:
      • Control allowed schemes (e.g., https, http, mailto) using allowLinkSchemes() or allowMediaSchemes().
      • Control allowed hosts using allowLinkHosts() or allowMediaHosts().
      • Enable relative URLs with allowRelativeLinks() or allowRelativeMedias().
      • Automatically upgrade links using forceHttpsUrls().
    • Custom Logic:
      • Use withAttributeSanitizer(AttributeSanitizerInterface $sanitizer) to apply custom sanitization logic to attributes.
    use Symfony\Component\HtmlSanitizer\HtmlSanitizerConfig;
    use Symfony\Component\HtmlSanitizer\HtmlSanitizer;
    
    $config = (new HtmlSanitizerConfig())
        ->allowSafeElements()
        ->allowElement('a', ['title'])
        ->blockElement('section') // Removes section, keeps children
        ->dropElement('div')      // Removes div and its children
        ->allowAttribute('data-custom-attr', '*')
        ->forceAttribute('a', 'rel', 'noopener noreferrer')
        ->allowLinkSchemes(['https', 'http'])
        ->allowRelativeLinks();
    
    $sanitizer = new HtmlSanitizer($config);
  3. Sanitize HTML input with HtmlSanitizer

    8.2

    Once a HtmlSanitizerConfig is defined, instantiate the HtmlSanitizer class with that configuration. You can then sanitize strings using different contexts.

    • sanitize(string $html): Sanitizes the input for use in the <body> context. Tags only allowed in <head> will be removed.
    • sanitizeFor(string $context, string $html): Sanitizes the input for a specific tag context:
      • For 'head': Sanitizes for use inside a <head> tag.
      • For 'title' or 'textarea': Encodes the input as HTML entities.
      • For 'div' or 'section': Sanitizes as if it were in the <body>.
    use Symfony\Component\HtmlSanitizer\HtmlSanitizerConfig;
    use Symfony\Component\HtmlSanitizer\HtmlSanitizer;
    
    $config = (new HtmlSanitizerConfig())->allowSafeElements();
    $sanitizer = new HtmlSanitizer($config);
    
    // Standard body sanitization
    $safeHtml = $sanitizer->sanitize($userInput);
    
    // Context-specific sanitization
    $headHtml = $sanitizer->sanitizeFor('head', $userInput);
    $entityHtml = $sanitizer->sanitizeFor('title', $userInput);