milenmk / laravel-blacklist
A Laravel package for blacklist validation of user input
Installs: 9
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/milenmk/laravel-blacklist
Requires
- php: ^8.0
- illuminate/support: ^8.0|^9.0|^10.0|^11.0|^12.0
Requires (Dev)
- brianium/paratest: ^7.9
- laravel/pint: ^1.13
- orchestra/testbench: ^10.2
- phpunit/phpunit: ^12.1
- squizlabs/php_codesniffer: ^3.11
- tightenco/duster: ^3.1
Conflicts
- laravel/framework: <8.0
README
Laravel Blacklist: A robust content filtering solution for Laravel applications that provides comprehensive validation against unwanted user input. This package offers dual-layer protection with both system blacklist words (preventing username squatting and system impersonation) and profanity/offensive terms filtering.
Key features:
- Intelligent Word Boundary Matching: Prevents false positives while catching problematic content.
- Flexible Filtering Modes: Use system blacklist only, profanity filtering only, or both simultaneously.
- Advanced Matching Strategies:
- Exact: Whole word matching (default).
- Fuzzy: Catch typos using Levenshtein distance (e.g., "admin" matches "adm1n").
- Substitution: Catch "leet speak" substitutions (e.g., "h3ll0").
- Context-Aware Validation: Define different validation rules for different fields (e.g., stricter rules for usernames vs comments).
- Whitelist & Ignore Patterns: Globally whitelist terms or use regex to ignore specific patterns.
- Customizable Word Lists: Easily extend or modify lists via configuration.
- Detailed Error Messages: Users receive context-aware validation feedback.
- Built-in Security Logging: Support for custom log channels.
- Simple Integration: Works with Laravel controllers, Livewire components, and forms.
- Zero Dependencies: Lightweight and efficient.
- Optional Logging Support: Pass a custom log channel to capture violations or auditing.
Perfect for applications requiring content moderation, user registration systems, comment sections, or any user-generated content that needs protection against inappropriate language or system term abuse.
Installation
-
Install the package via composer:
composer require milenmk/laravel-blacklist -
Publish the configuration file
The package works out of the box with default settings, but you can customize it by publishing the config file:
php artisan vendor:publish --tag=blacklist-configThis will create a
config/blacklist.phpfile where you can:- Choose which word lists to use (system blacklist, profanity, or both)
- Customize the blacklisted terms in each list
Note: If you don't publish the config file, the package will use the default configuration with the 'blacklist' mode enabled.
-
Publish the package language file
php artisan vendor:publish --tag=blacklist-translations
Configuration Options
The package provides three modes for filtering content:
```php
// config/blacklist.php
return [
// Choose which lists to use: 'blacklist', 'profanity', or 'both'
'mode' => 'blacklist',
// System blacklist words (usernames, reserved terms, etc.)
'blacklist' => [
'admin',
'system',
// ...
],
// Profanity and offensive terms
'profanity' => [
// Common profanity words
// ...
],
// Whitelist words that should never be flagged
'whitelist' => [
'Laravel',
],
// Regex patterns to ignore
'ignore_patterns' => [
'/^uuid-.*$/',
],
// Advanced matching strategies
'lists' => [
'custom_list' => [
'terms' => ['forbidden'],
'matching' => 'fuzzy', // Options: exact, fuzzy, substitution
'threshold' => 1, // For fuzzy matching
],
],
// Per-field contexts
'contexts' => [
'username' => ['blacklist', 'custom_list'],
],
];
```
Usage
Basic controller
use Milenmk\LaravelBlacklist\Services\BlacklistService; class YourController { protected BlacklistService $blacklistService; public function __construct(BlacklistService $blacklistService) { $this->blacklistService = $blacklistService; } public function store(Request $request) { // Validate request... // Check fields against blacklisted words $blacklistErrors = $this->blacklistService->checkFields([ 'name' => $request->input('name'), 'email' => $request->input('email'), // Add any other fields you want to check ]); if (!empty($blacklistErrors)) { return redirect()->back()->withErrors($blacklistErrors); } // Continue with your logic... } }
Livewire component
use Livewire\Component; use Milenmk\LaravelBlacklist\Services\BlacklistService; class YourComponent extends Component { protected BlacklistService $blacklistService; public function mount(): void { $this->blacklistService = app(BlacklistService::class); }
Livewire form
use Livewire\Form; use Milenmk\LaravelBlacklist\Services\BlacklistService; class YourForm extends Form { protected BlacklistService $blacklistService; public function __construct($componentOrService = null, $propertyName = null) { parent::__construct($componentOrService, $propertyName); $this->blacklistService = app(BlacklistService::class); } }
Advanced Usage
1. Blacklist Validation Rule
You can use the BlacklistRule in your form requests or validation logic.
use Milenmk\LaravelBlacklist\Rules\BlacklistRule; // ... public function rules(): array { return [ // Uses 'username' as the context (checks 'contexts.username' in config) 'username' => ['required', new BlacklistRule()], // Explicitly specify the context 'bio' => ['required', new BlacklistRule('strict_bio')], ]; }
2. Route Middleware
Protect your routes using the blacklist middleware.
// Protect a route using the 'comment' context Route::post('/comments', ...)->middleware('blacklist:comment'); // If no context is provided, it uses the field names from the request as contexts Route::post('/profile', ...)->middleware('blacklist');
3. Whitelist and Ignore Patterns
You can define global exceptions in your configuration file:
- Whitelist: Exact words that should never be blocked (e.g., "Analyst").
- Ignore Patterns: Regex patterns to ignore (e.g., ignoring UUIDs or specific codes).
// config/blacklist.php 'whitelist' => ['Analyst', 'Dickson'], 'ignore_patterns' => ['/^TX-\d+$/'],
4. Advanced Matching Strategies
You can define custom lists with specific matching strategies in config/blacklist.php:
'lists' => [ 'strict_list' => [ 'terms' => ['forbidden'], 'matching' => 'exact', ], 'typo_list' => [ 'terms' => ['important'], 'matching' => 'fuzzy', // Uses Levenshtein distance 'threshold' => 1, // Matches "1mportant" ], 'leet_list' => [ 'terms' => ['hacker'], 'matching' => 'substitution', // Matches "h4ck3r" ], ],
5. Context-Aware Validation
Map different contexts (fields) to specific lists:
'contexts' => [ 'username' => ['blacklist', 'strict_list'], 'comment' => ['profanity', 'typo_list', 'leet_list'], ],
Custom Log Channel
You can specify a custom log channel:
$blacklistErrors = $this->blacklistService->checkFields([ 'name' => $request->input('name'), 'email' => $request->input('email'), ], 'security');
Switching Modes
You can change the filtering mode in your config file:
// config/blacklist.php 'mode' => 'blacklist', // Only check system blacklist words // OR 'mode' => 'profanity', // Only check profanity/offensive words // OR 'mode' => 'both', // Check both lists
The error messages will indicate which list the matched term belongs to:
- "The {field} contains the blacklisted word: "{term}""
- "The {field} contains the profanity word: "{term}""
Word Matching
This package uses whole word boundary matching to prevent false positives. For example:
- "admin" will match in "admin user" but not in "administrator" or "badminton"
- "damn" will match in "that's damn good" but not in "condamnation"
This ensures that legitimate content isn't incorrectly flagged while still catching problematic terms.
Enhanced Attribute Name Support (New)
The checkFields() method now accepts an optional third parameter $attributes — an associative array mapping field
names to human-readable labels:
$attributes = [ 'last_name' => 'Last Name', 'name' => 'Name', 'email' => 'Email Address', // Add your fields here ]; $blacklistErrors = $this->blacklistService->checkFields($input, null, $attributes);
This enables error messages to display friendly field names instead of raw input keys. For example:
The Last Name contains a blacklisted word: administrator
instead of
The last_name contains a blacklisted word: administrator
This ensures your error messages remain clear and consistent with Laravel's native validation attribute naming conventions, improving user experience.
Changelog
Please see CHANGELOG.md for more information on what has changed recently.
Support My Work
If this package saves you time, you can support ongoing development:
👉 Become a Patron
Other Packages
Check out my other Laravel packages:
- Laravel GDPR Cookie Manager - GDPR-compliant cookie consent management with user preference tracking
- Laravel Email Change Confirmation - Secure email change confirmation system
- Laravel GDPR Exporter - GDPR-compliant data export functionality
- Laravel Locations - Add Countries, Cities, Areas, Languages and Currencies models to your Laravel application
- Laravel Rate Limiting - Advanced rate limiting capabilities with exponential backoff
- Laravel Datatables and Forms - Easy to use package to create datatables and forms for Livewire components
License
This package is licensed under the MIT License. See the LICENSE file for more details.
Disclaimer
This package is provided "as is", without warranty of any kind, express or implied, including but not limited to warranties of merchantability, fitness for a particular purpose, or noninfringement.
The author(s) make no guarantees regarding the accuracy, reliability, or completeness of the code, and shall not be held liable for any damages or losses arising from its use.
Please ensure you thoroughly test this package in your environment before deploying it to production.