mirror of
https://github.com/coollabsio/coolify.git
synced 2026-10-28 17:44:36 +08:00
86 lines
3.3 KiB
PHP
86 lines
3.3 KiB
PHP
<?php
|
|
|
|
use App\Logging\RedactSensitiveAuditData;
|
|
use App\Logging\RedactSensitiveData;
|
|
use App\Services\Security\SensitiveDataRedactor;
|
|
use Illuminate\Log\Logger;
|
|
use Monolog\Handler\TestHandler;
|
|
use Monolog\Logger as MonologLogger;
|
|
|
|
it('redacts messages, nested context, and exceptions before a handler receives the record', function () {
|
|
$secret = 'coolify-canary-secret-a91f0c';
|
|
$handler = new TestHandler;
|
|
$logger = new Logger(new MonologLogger('test', [$handler]));
|
|
|
|
(new RedactSensitiveData(new SensitiveDataRedactor))($logger);
|
|
|
|
$logger->error(
|
|
"Deployment failed with password={$secret}",
|
|
[
|
|
'headers' => ['Authorization' => "Bearer {$secret}"],
|
|
'exception' => new RuntimeException("token={$secret}"),
|
|
],
|
|
);
|
|
|
|
$record = $handler->getRecords()[0];
|
|
$serializedRecord = serialize([$record->message, $record->context, $record->extra]);
|
|
|
|
expect($serializedRecord)
|
|
->not->toContain($secret)
|
|
->toContain(REDACTED)
|
|
->and($record->context['exception']['trace'])->toBeString()->not->toBeEmpty();
|
|
});
|
|
|
|
it('keeps redacted traces and previous exceptions', function () {
|
|
$secret = 'coolify-canary-secret-previous';
|
|
$handler = new TestHandler;
|
|
$logger = new Logger(new MonologLogger('test', [$handler]));
|
|
|
|
(new RedactSensitiveData(new SensitiveDataRedactor))($logger);
|
|
|
|
$logger->error('Failed', [
|
|
'exception' => new RuntimeException('outer', 0, new RuntimeException("password={$secret}")),
|
|
]);
|
|
|
|
$exception = $handler->getRecords()[0]->context['exception'];
|
|
|
|
expect($exception['trace'])->toContain('#0')
|
|
->and($exception['previous']['message'])->toBe('password='.REDACTED)
|
|
->and(serialize($exception))->not->toContain($secret);
|
|
});
|
|
|
|
it('wires redaction into all persistent and remote log channels', function () {
|
|
$configuration = file_get_contents(__DIR__.'/../../config/logging.php');
|
|
|
|
expect($configuration)
|
|
->toContain("'channels' => ['single']")
|
|
->toContain("env('LOG_LEVEL', 'debug')")
|
|
->not->toContain("env('LOG_LEVEL', 'info')")
|
|
->and(substr_count($configuration, 'RedactSensitiveData::class'))->toBe(9)
|
|
->and($configuration)->toMatch("/'audit' => \\[[^\\]]*'tap' => \\[RedactSensitiveAuditData::class\\]/s");
|
|
});
|
|
|
|
it('keeps email addresses in the audit log while still redacting secrets', function () {
|
|
$secret = 'coolify-canary-secret-audit';
|
|
$handler = new TestHandler;
|
|
$logger = new Logger(new MonologLogger('audit', [$handler]));
|
|
|
|
(new RedactSensitiveAuditData(new SensitiveDataRedactor))($logger);
|
|
|
|
$logger->info("User changed password={$secret}", ['user_email' => 'admin@example.com', 'token' => $secret]);
|
|
|
|
$record = $handler->getRecords()[0];
|
|
|
|
expect($record->context['user_email'])->toBe('admin@example.com')
|
|
->and($record->context['token'])->toBe(REDACTED)
|
|
->and($record->message)->toBe('User changed password='.REDACTED);
|
|
});
|
|
|
|
it('redacts email addresses in the default channels', function () {
|
|
$redactor = new SensitiveDataRedactor;
|
|
|
|
expect($redactor->redactText('mail admin@example.com'))->toBe('mail '.REDACTED)
|
|
->and($redactor->withoutEmailRedaction()->redactText('mail admin@example.com'))->toBe('mail admin@example.com')
|
|
->and($redactor->redactText('mail admin@example.com'))->toBe('mail '.REDACTED);
|
|
});
|