Skip to content

[12.x] Add Str::sanitize() for HTML sanitization#59194

Open
SanderMuller wants to merge 3 commits intolaravel:12.xfrom
SanderMuller:feature/str-sanitize
Open

[12.x] Add Str::sanitize() for HTML sanitization#59194
SanderMuller wants to merge 3 commits intolaravel:12.xfrom
SanderMuller:feature/str-sanitize

Conversation

@SanderMuller
Copy link
Contributor

Summary

Adds Str::sanitize() and Stringable::sanitize() methods that wrap Symfony's html-sanitizer component, providing a clean API for HTML sanitization, following the same pattern as Str::markdown().

Usage

// Safe defaults: allows Symfony's curated safe element list (no script, style, iframe, etc.)
Str::sanitize('<p>Hello <script>alert("xss")</script></p>');
// '<p>Hello </p>'

// Allow specific elements
Str::sanitize($html, ['p', 'a', 'strong', 'em']);

// Allow elements with specific attributes
Str::sanitize($html, ['a' => ['href', 'title'], 'img' => ['src', 'alt']]);

// Full control via closure for advanced configuration
Str::sanitize($html, fn (HtmlSanitizerConfig $config) => $config
    ->allowSafeElements()
    ->forceHttpsUrls()
    ->allowRelativeLinks()
);

// Fluent
Str::of($userInput)->sanitize()->toString();

Motivation

Laravel has e() for escaping and Str::markdown() for rendering Markdown, but no built-in way to sanitize HTML, allowing safe elements through while stripping dangerous ones. This is a common need when accepting rich text input (WYSIWYG editors, user-submitted content, etc.). The current options are strip_tags() (too aggressive, removes everything) or pulling in a package.

This follows the same approach as Str::markdown(): a static method on Str that wraps a well-maintained library (symfony/html-sanitizer, same ecosystem as the 10+ Symfony packages Laravel already depends on) with a simple, expressive API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant