PHPackages                             yorcreative/laravel-scrubber - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. yorcreative/laravel-scrubber

ActiveLibrary[Framework](/categories/framework)

yorcreative/laravel-scrubber
============================

A laravel package that scrubs sensitive information for you.

v3.8.0(2mo ago)15467.2k↓19.8%14[1 PRs](https://github.com/YorCreative/Laravel-Scrubber/pulls)2MITPHPPHP ^8.2|^8.3|^8.4|^8.5CI passing

Since Aug 16Pushed 2mo ago3 watchersCompare

[ Source](https://github.com/YorCreative/Laravel-Scrubber)[ Packagist](https://packagist.org/packages/yorcreative/laravel-scrubber)[ GitHub Sponsors](https://github.com/yorcreative)[ RSS](/packages/yorcreative-laravel-scrubber/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (14)Versions (50)Used By (2)

 [ ![Logo](content/logo-2-color.png) ](https://github.com/YorCreative)

### Laravel Scrubber

[](#laravel-scrubber)

[![GitHub license](https://camo.githubusercontent.com/4a64298e46c73d99ffff25b55b088395353bdd7f210c0d5d3cabf86a5e6ee80d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f596f7243726561746976652f4c61726176656c2d5363727562626572)](https://github.com/YorCreative/Laravel-Scrubber/blob/main/LICENSE.md)[![GitHub stars](https://camo.githubusercontent.com/0a40aea4ed2657afb5aaa33fec672d59e0e71f8cc4899dd40d1bb399ff915444/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f596f7243726561746976652f4c61726176656c2d5363727562626572)](https://github.com/YorCreative/Laravel-Scrubber/stargazers)[![GitHub issues](https://camo.githubusercontent.com/e7a5dddc8083f226f706a134b617fa0690e32cfd5893b6c84888ad97b2a51ad9/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f596f7243726561746976652f4c61726176656c2d5363727562626572)](https://github.com/YorCreative/Laravel-Scrubber/issues)[![GitHub forks](https://camo.githubusercontent.com/466db57d0cbb3ceb062b6cdc636ba6c71e0fba5935d5518b529a8f9bfb05a733/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f596f7243726561746976652f4c61726176656c2d5363727562626572)](https://github.com/YorCreative/Laravel-Scrubber/network)[![Packagist Downloads](https://camo.githubusercontent.com/ffcb32e140705ba1a479645643adcb7028e047b47f7cdb94c84b29b0fe22217c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f596f7243726561746976652f4c61726176656c2d53637275626265723f636f6c6f723d677265656e)](https://camo.githubusercontent.com/ffcb32e140705ba1a479645643adcb7028e047b47f7cdb94c84b29b0fe22217c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f596f7243726561746976652f4c61726176656c2d53637275626265723f636f6c6f723d677265656e)[![PHPUnit](https://github.com/YorCreative/Laravel-Scrubber/actions/workflows/phpunit.yml/badge.svg)](https://github.com/YorCreative/Laravel-Scrubber/actions/workflows/phpunit.yml)

A Laravel package to scrub sensitive information that breaks operational security policies from being leaked on accident *or not* by developers.

Requirements
------------

[](#requirements)

- PHP 8.2, 8.3, 8.4, or 8.5
- Laravel 10.x, 11.x, or 12.x

Installation
------------

[](#installation)

install the package via composer:

```
composer require yorcreative/laravel-scrubber
```

Publish the packages assets.

```
php artisan vendor:publish --provider="YorCreative\Scrubber\ScrubberServiceProvider"
```

Configuration
-------------

[](#configuration)

Adjust the configuration file to suite your application, located in `/config/scrubber.php`.

```
return [
    /**
     * Specify the string to use to redact the data
     */
    'redaction' => '**redacted**',

    'secret_manager' => [
        'key' => env('APP_KEY'),
        'cipher' => 'AES-256-CBC',
        'enabled' => false,
        'providers' => [
            // See "Secret Manager Providers" section for full configuration options
            'gitlab' => ['enabled' => false, /* ... */],
            'aws' => ['enabled' => false, /* ... */],
            'vault' => ['enabled' => false, /* ... */],
            'azure' => ['enabled' => false, /* ... */],
            'google' => ['enabled' => false, /* ... */],
        ],
    ],

    /**
     * Specify the regexes to load
     * You can use a wildcard (*) to load all regexes in all `custom_regex_namespaces` and the default core regexes.
     * Otherwise, specify the regexes you want to load either by qualified class name or by unqualified (base) class name,
     * which will then search the `custom_regex_namespaces` and the default core regexes for a match.
     */
    'regex_loader' => ['*'],

    /**
     * Specify regex patterns to exclude from loading when using the regex loader
     * This allows fine-grained control over which regex patterns are loaded, especially useful when using wildcard (*) in regex_loader
     *
     * You can exclude patterns using any of these formats:
     * - Fully qualified class name (e.g., 'YorCreative\Scrubber\RegexCollection\GoogleApi')
     * - Base class name (e.g., 'GoogleApi', 'EmailAddress')
     * - Pattern constant from RegexCollection (e.g., RegexCollection::$GOOGLE_API)
     * - Custom namespace class (e.g., 'App\Scrubber\RegexCollection\HerokuApiKey')
     *
     * Example:
     * [
     *     'GoogleApi',
     *     'YorCreative\Scrubber\RegexCollection\EmailAddress',
     *     RegexCollection::$HEROKU_API_KEY,
     *     'App\Scrubber\RegexCollection\HerokuApiKey'
     * ]
     */
    'exclude_regex' => [],

    /**
     * Specify namespaces from which regexes will be loaded when using the wildcard (*)
     * for the regex_loader or where you use unqualified class names.
     */
    'custom_regex_namespaces' => [
       'App\\Scrubber\\RegexCollection',
    ],

    /**
     * Specify config keys for which the values will be scrubbed
     * You should use the dot notation to specify the keys
     * You can use wildcards (*) to match multiple keys
     *
     *  - 'database.connections.*.password'
     *  - 'app.secrets.*'
     *  - 'app.some.nested.key'
     */
    'config_loader' => [
        '*token',
        '*key',
        '*secret',
        '*password',
    ],

    /**
     * Minimum character length for config values to be treated as scrubbable.
     * Values shorter than this will be ignored to prevent overly aggressive
     * scrubbing (e.g., Livewire's release_token defaults to 'a').
     */
    'config_loader_min_length' => 4,

    /**
     * Config key patterns to exclude from scrubbing.
     * Supports wildcards (*) via Str::is().
     */
    'config_loader_exclusions' => [],

    /**
     * Specify the channels to tap into
     * You can use wildcards (*) to match multiple channels
     */
    'tap_channels' => false,
];
```

Usage
-----

[](#usage)

The scrubber can be utilized in two ways, the first one being a Log scrubber. A tap is added to detect and sanitize any sensitive information from hitting a log file. The second way is to integrate into your application and utilize the Scrubber directly. This way is particular useful if you, for example, would like to detect and sanitize any messages on a messaging platform.

### Logging Detection &amp; Sanitization

[](#logging-detection--sanitization)

```
Log::info('some message', [
    'context' => 'accidental',
    'leak_of' => [
        'jwt' => ''
    ]
])

// testing.INFO: some message {"context":"accidental","leak_of":{"jwt": '**redacted**'}}

Log::info('')

// testing.INFO: **redacted**
```

### Direct Usage for Detection &amp; Sanitization

[](#direct-usage-for-detection--sanitization)

```
Scrubber::processMessage([
    'context' => 'accidental',
    'leak_of' => [
        'jwt' => ''
    ]
]);
// [
//     "context" => "accidental"
//     "leak_of" => [
//         "jwt" => "**redacted**"
//     ]
// ];

Scrubber::processMessage('');
// **redacted**
```

### Detection Statistics API

[](#detection-statistics-api)

Track what patterns are matching and how often:

```
// Get scrubbing statistics for the current request
$stats = Scrubber::getStats();
// ['total_scrubs' => 5, 'patterns_matched' => ['JsonWebToken' => 2, 'EmailAddress' => 3]]

// Test a string without modifying stats - useful for debugging
$result = Scrubber::test('Contact: john@example.com, SSN: 123-45-6789');
// [
//     'matched' => true,
//     'patterns' => ['EmailAddress' => 1, 'SocialSecurityNumber' => 1],
//     'scrubbed' => 'Contact: **redacted**, SSN: ***-**-****'
// ]

// Reset statistics between requests
Scrubber::resetStats();
```

### Events

[](#events)

The scrubber can dispatch a `SensitiveDataDetected` event each time a pattern matches during scrubbing. This is useful for alerting, metrics, or audit logging.

Enable events in your config:

```
'events' => [
    'enabled' => true,
],
```

The event carries three public properties:

PropertyTypeDescription`patternName``string`The class basename of the matched pattern (e.g. `JsonWebToken`)`hitCount``int`Number of matches found for that pattern in the content`context``string`Either `log` (triggered via log tap) or `manual` (triggered via `Scrubber::processMessage()`)Register a listener in your `EventServiceProvider` or with the `Event` facade:

```
use YorCreative\Scrubber\Events\SensitiveDataDetected;

Event::listen(SensitiveDataDetected::class, function (SensitiveDataDetected $event) {
    // $event->patternName  — e.g. 'JsonWebToken'
    // $event->hitCount     — e.g. 2
    // $event->context      — 'log' or 'manual'
});
```

Log Channel Opt-in
------------------

[](#log-channel-opt-in)

This package provides you the ability to define through the configuration file what channels you want to scrub specifically. By default, this package ships with a wildcard value and opts in to scrub all the log channels in your application.

### Defining Log Channel Opt-in

[](#defining-log-channel-opt-in)

To opt in to one or more channels, list the channel(s) name into the `tap_channels` array in the config.

```
'tap_channels' => [
    'single',
    'papertrail'
]
```

To disable tap logging functionality and use the package independently and not tap your Laravel application logging, modify the config file by setting the tap\_channels field as follows:

```
'tap_channels' => false
```

Regex Class Opt-in
------------------

[](#regex-class-opt-in)

You have the ability through the configuration file to define what regex classes you want loaded into the application when it is bootstrapped. By default, this package ships with a wildcard value.

### Regex Collection &amp; Defining Opt-in

[](#regex-collection--defining-opt-in)

To opt in, utilize the static properties on the [RegexCollection](https://github.com/YorCreative/Laravel-Scrubber/blob/main/src/Repositories/RegexCollection.php)class.

```
 'regex_loader' => [
        RegexCollection::$GOOGLE_API,
        RegexCollection::$AUTHORIZATION_BEARER,
        RegexCollection::$CREDIT_CARD_AMERICAN_EXPRESS,
        RegexCollection::$CREDIT_CARD_DISCOVER,
        RegexCollection::$CREDIT_CARD_VISA,
        RegexCollection::$JSON_WEB_TOKEN
    ],
```

> **Note**: The package includes 31 built-in patterns. See all available patterns in [RegexCollection.php](https://github.com/YorCreative/Laravel-Scrubber/blob/main/src/Repositories/RegexCollection.php).

### PII Detection with Partial Masking

[](#pii-detection-with-partial-masking)

The following patterns use contextual replacement values for improved readability instead of the generic `**redacted**`:

PatternDetectsMasked Output`RegexCollection::$SOCIAL_SECURITY_NUMBER`US Social Security Numbers`***-**-****``RegexCollection::$PHONE_NUMBER`Phone numbers (US/International)`(***) ***-****``RegexCollection::$IP_ADDRESS_V4`IPv4 addresses`***.***.***.***``RegexCollection::$IP_ADDRESS_V6`IPv6 addresses`****:****:****:...``RegexCollection::$IBAN`International Bank Account Numbers`********************````
Scrubber::processMessage('SSN: 123-45-6789, Phone: (555) 123-4567');
// "SSN: ***-**-****, Phone: (***) ***-****"

Scrubber::processMessage('Server IP: 192.168.1.1');
// "Server IP: ***.***.***.***"
```

### Opting Into Custom Extended Classes

[](#opting-into-custom-extended-classes)

> To create custom scrubbers, see the [Extending the Scrubber](#extending-the-scrubber) section.

The `regex_loader` array takes strings, not objects. To opt in to specific custom extended regex classes, define the class name as a string.

For example if I have a custom extended class as such:

```
