Files
coolify/tests/Unit/RedactSensitiveDataLoggingTest.php
T
Andras BacsaiandClaude Opus 5.5 a70e856882 test: remove tests that do not test behavior and strengthen weak ones
- Remove tests that only check markup, CSS, static text, wire:key strings,
  framework behavior, copied app logic, or expect(true)
- Replace source-grep and Reflection checks of security fixes with tests
  that run the real code (shell quoting, locked properties, 403 checks,
  webhook fork trust, log redaction, Sentinel token cleanup)
- Assert response bodies and unchanged data on API error paths
- Run the Traefik version job through handle() instead of private methods
- Update stale tests for scheduled task props, the default Postgres image,
  and the disabled transfer link of unvalidated servers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 08:47:56 +01:00

75 lines
2.8 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('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);
});