joomla/filter
joomla/filter provides input and output filtering tools for PHP apps, helping sanitize content by allowing or blocking specific HTML tags and attributes. Includes OutputFilter helpers (e.g., URL-safe strings; optional Joomla\Language).
Installation:
composer require joomla/filter "~3.0"
For PHP 8.3+ projects, use ~4.0 instead.
First Use Case: Sanitize user input in a Laravel controller or request handler:
use Joomla\Filter\InputFilter;
$cleanInput = InputFilter::clean(
$userInput,
InputFilter::ONLY_ALLOW_DEFINED_TAGS,
['p', 'b', 'i', 'a']
);
Where to Look First:
Request Sanitization Pipeline:
// In a Laravel Form Request or middleware
public function sanitize($input, array $allowedTags = ['p', 'a'])
{
return InputFilter::clean(
$input,
InputFilter::ONLY_ALLOW_DEFINED_TAGS,
$allowedTags
);
}
Service Provider Integration:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton('filter', function () {
return new InputFilter();
});
}
Inject via constructor:
public function __construct(private InputFilter $filter) {}
Dynamic Whitelists:
// Allow tags based on user role
$allowedTags = auth()->user()->role === 'admin' ? ['div', 'span'] : ['p', 'b'];
$cleanHtml = $this->filter->clean($input, InputFilter::ONLY_ALLOW_DEFINED_TAGS, $allowedTags);
Attribute-Level Control:
// Allow only href in <a> tags
$cleanHtml = InputFilter::clean(
$input,
InputFilter::ONLY_ALLOW_DEFINED_TAGS | InputFilter::ONLY_ALLOW_DEFINED_ATTRIBUTES,
['a'],
['href']
);
Form Handling:
validate() or sanitize() methods of Laravel Form Requests.public function rules()
{
return ['content' => 'required|string'];
}
public function sanitize($attribute, $value)
{
return InputFilter::clean($value, InputFilter::ONLY_ALLOW_DEFINED_TAGS, ['p', 'b']);
}
API Payloads:
$data = json_decode($request->getContent(), true);
$data['description'] = InputFilter::clean($data['description'], ...);
CMS Content:
DetailPanel or custom fields:
// Nova Field
public function resolve($resource, $attribute)
{
return InputFilter::clean($resource->$attribute, ...);
}
Laravel Validation Rules: Extend Laravel’s validation with custom rules:
use Joomla\Filter\InputFilter;
class Sanitize extends FormRequest
{
public function rules()
{
return ['bio' => ['required', new SanitizeRule(['p', 'a'])]];
}
}
class SanitizeRule extends Rule
{
public function __construct(private array $allowedTags)
{
parent::__construct();
}
public function passes($attribute, $value)
{
return InputFilter::clean($value, InputFilter::ONLY_ALLOW_DEFINED_TAGS, $this->allowedTags) !== false;
}
}
Blade Directives: Create a custom Blade directive for sanitized output:
// app/Providers/BladeServiceProvider.php
Blade::directive('sanitize', function ($expression) {
return "<?php echo InputFilter::clean({$expression}, InputFilter::ONLY_ALLOW_DEFINED_TAGS, ['p', 'b']); ?>";
});
Usage:
{!! sanitize($user->bio) !!}
Event Listeners:
Sanitize data on model events (e.g., saving):
public function saving(Post $post)
{
$post->content = InputFilter::clean(
$post->content,
InputFilter::ONLY_ALLOW_DEFINED_TAGS,
['h1', 'p', 'ul', 'li']
);
}
PHP Version Mismatch:
~3.0 for older Laravel projects (e.g., Laravel 9).False Positives in Sanitization:
<img src="..."> if src isn’t whitelisted).Nested Tag Issues:
stripImages/stripIframes.~3.0.2 or later.Attribute Filtering Quirks:
ONLY_ALLOW_DEFINED_ATTRIBUTES can strip valid attributes if not configured carefully.['href', 'title'] for <a> tags).Performance Overhead:
Unexpected Output:
InputFilter::clean() with InputFilter::RETURN_ERRORS flag to debug:
$result = InputFilter::clean($input, InputFilter::RETURN_ERRORS, ['p']);
if ($result === false) {
dd(InputFilter::getErrors()); // Inspect why sanitization failed
}
XSS Evasion Bypasses:
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<a href="javascript:alert(1)">Click</a>
~4.0.1+ (removes common evasion chars) or manually add rules.Whitelist Misconfigurations:
$config = InputFilter::getConfig();
dd($config->allowedTags, $config->allowedAttributes);
Static vs. Instance Methods:
InputFilter::clean()) use global config.$filter = new InputFilter();
$filter->setAllowedTags(['div', 'span']);
$clean = $filter->clean($input);
OutputFilter Dependencies:
OutputFilter::stringURLSafe() requires joomla/language package.composer require joomla/language
Legacy Constant Names:
TAGS_WHITELIST).ONLY_ALLOW_DEFINED_TAGS).Custom Filters:
Extend InputFilter to add domain-specific rules:
class CustomFilter extends InputFilter
{
public function cleanCustom($input)
{
return $this->clean($input, InputFilter::ONLY_ALLOW_DEFINED_TAGS, ['custom']);
}
}
Event-Driven Sanitization: Use Laravel events to trigger sanitization:
// In a service provider
event(new SanitizeEvent($input));
Handle with a listener:
public function handle(SanitizeEvent $event)
{
$event->setSanitized(InputFilter::clean($event->input, ...));
}
Testing Helpers: Create a test
How can I help you explore Laravel packages today?