I recently released a small open-source Symfony bundle called MaskedBundle.
The reason for building it was quite simple: logs are useful, but sometimes they can contain values that should not be there.
I wanted something I could reuse in Symfony projects to mask sensitive values before they reach logs or other diagnostic output.
Basic usage
Installation:
composer require alkinbg/masked-bundle
For example:
use Masked\Bundle\SensitiveDataMasker;
final class PaymentService
{
public function __construct(
private readonly SensitiveDataMasker $masker,
) {
}
public function example(): string
{
return $this->masker->mask(
'Card: 4111111111111111',
);
}
}
The result:
Card: ████████████████
At the moment automatic detection focuses on payment card numbers.
I deliberately don't try to automatically detect every possible token, password or secret. There are too many formats and guessing can easily produce false positives.
Instead, values known by the application can be passed explicitly:
$token = 'secret-access-token';
$masked = $sensitiveDataMasker->mask(
'Authentication failed for token ' . $token,
sensitiveValues: [$token],
);
Result:
Authentication failed for token ███████████████████
Both approaches can be used together.
Arrays and logs
There is also a StructuredDataMasker for arrays:
$masked = $structuredDataMasker->mask([
'customer' => [
'card' => '4111111111111111',
],
]);
The bundle also has optional Monolog integration, so messages and context can be masked before they are written to the log.
I kept the Monolog part optional because the masking services can also be useful on their own.
One thing I cared about
Because this code handles sensitive data, I didn't want unusual input to result in partially checked data being returned.
There are limits for things like very large arrays and explicit-value searches. If a detection budget is exceeded, the masking operation prefers to fail closed.
It adds some complexity internally, but I think it is the safer behaviour for this kind of library.
That's it
MaskedBundle currently requires PHP 8.4.1+ and Symfony 8.1+.
It is MIT licensed:
https://github.com/alkinbg/masked-bundle
https://packagist.org/packages/alkinbg/masked-bundle
If you use Symfony and have any feedback, I'd be happy to hear it.
Top comments (0)