Пакет · logger

Маскирование чувствительных данных

Секреты легко попадают в логи — тело запроса с password, заголовок с токеном authorization. SensitiveMaskingProcessor скрывает их до того, как они достигнут любого обработчика, так что они никогда не попадают на диск или в ваш агрегатор.

Добавьте процессор к каналу

Процессор опционален — добавляйте его после сборки менеджера. Навесьте его на нижележащий экземпляр Monolog у канала:

php
use Flytachi\Winter\Logger\Processor\SensitiveMaskingProcessor;

$manager->channel('http')->monolog()->pushProcessor(new SensitiveMaskingProcessor());

Теперь любой совпавший ключ заменяется на *** и в context, и в extra:

php
LoggerFactory::getLogger(self::class)->info('login attempt', [
  'username' => 'alice',
  'password' => 'hunter2',      // ← замаскировано
  'metadata' => [
      'token' => 'secret-jwt',  // ← вложенное, тоже замаскировано
  ],
]);
text
[2024-01-01 12:00:00] [INFO ] -http- [4821] (AuthService): login attempt {"username":"alice","password":"***","metadata":{"token":"***"}}

Что оно сопоставляет

  • Регистронезависимо по ключам — Password, PASSWORD и password совпадают одинаково.
  • Рекурсивно — вложенные массивы обходятся на любую глубину.
  • Применяется и к context вызова, и к влитому extra.

Ключи, маскируемые по умолчанию (все заменяются на ***):

text
password  passwd  secret  token  access_token  refresh_token
api_key  apikey  authorization  auth  cookie  set-cookie
credit_card  card_number  cvv  ssn  pin

Авторитетный список — в Справочнике формата логов.

Добавьте свои ключи

Передайте дополнительные ключи в конструктор — они объединяются со значениями по умолчанию:

php
$processor = new SensitiveMaskingProcessor(['patient_id', 'insurance_number']);

$manager->channel('http')->monolog()->pushProcessor($processor);

Примените ко всем каналам

Глобального переключателя нет — добавьте процессор к каждому каналу, который хотите маскировать. Небольшой цикл на бутстрапе покроет все:

php
foreach (['http', 'cli', 'sys'] as $name) {
  if ($manager->hasChannel($name)) {
      $manager->channel($name)->monolog()->pushProcessor(new SensitiveMaskingProcessor());
  }
}

Значения сопоставляются по ключу, а не по содержимому

Процессор скрывает по имени поля, а не по значению. Секрет, залогированный под ключом не из списка (например, data), или вставленный в строку сообщения, пойман не будет — держите секреты в осмысленно названных ключах контекста и никогда не помещайте их в текст сообщения.

Связанное