fix(firewall): register missing security audit events
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -39,6 +39,8 @@ class Module extends ModuleInstanceAbstract implements ModuleConsoleInterface, M
|
|||||||
SecurityEvent::AUTH_SUCCESS,
|
SecurityEvent::AUTH_SUCCESS,
|
||||||
SecurityEvent::ACCESS_DENIED,
|
SecurityEvent::ACCESS_DENIED,
|
||||||
SecurityEvent::BRUTE_FORCE_DETECTED,
|
SecurityEvent::BRUTE_FORCE_DETECTED,
|
||||||
|
SecurityEvent::RATE_LIMIT_EXCEEDED,
|
||||||
|
SecurityEvent::SUSPICIOUS_ACTIVITY,
|
||||||
] as $event) {
|
] as $event) {
|
||||||
$this->events->listen(
|
$this->events->listen(
|
||||||
'core',
|
'core',
|
||||||
|
|||||||
@@ -28,12 +28,18 @@ final class CoreModuleTest extends TestCase
|
|||||||
$module->boot();
|
$module->boot();
|
||||||
$definitions = $registry->definitions();
|
$definitions = $registry->definitions();
|
||||||
|
|
||||||
self::assertCount(5, $definitions);
|
self::assertCount(7, $definitions);
|
||||||
self::assertSame(['core'], array_values(array_unique(array_column($definitions, 'module'))));
|
self::assertSame(['core'], array_values(array_unique(array_column($definitions, 'module'))));
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
FirewallService::class,
|
FirewallService::class,
|
||||||
$registry->listeners(SecurityEvent::AUTH_FAILURE, DeliveryMode::Immediate)[0]->service,
|
$registry->listeners(SecurityEvent::AUTH_FAILURE, DeliveryMode::Immediate)[0]->service,
|
||||||
);
|
);
|
||||||
|
foreach ([SecurityEvent::RATE_LIMIT_EXCEEDED, SecurityEvent::SUSPICIOUS_ACTIVITY] as $event) {
|
||||||
|
$listeners = $registry->listeners($event, DeliveryMode::Deferred);
|
||||||
|
self::assertCount(1, $listeners);
|
||||||
|
self::assertSame(FirewallService::class, $listeners[0]->service);
|
||||||
|
self::assertSame('logSecurityEvent', $listeners[0]->method);
|
||||||
|
}
|
||||||
self::assertFalse($registry->frozen());
|
self::assertFalse($registry->frozen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -256,6 +256,59 @@ class FirewallServiceTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[TestDox('Rate-limit events retain their request and threshold audit data')]
|
||||||
|
public function testRateLimitAudit(): void
|
||||||
|
{
|
||||||
|
$this->store->expects($this->once())
|
||||||
|
->method('createLog')
|
||||||
|
->with(self::callback(static function (FirewallLogObject $log): bool {
|
||||||
|
$metadata = $log->getMetadata();
|
||||||
|
return $log->getEventType() === FirewallLogObject::EVENT_RATE_LIMIT
|
||||||
|
&& $log->getResult() === FirewallLogObject::RESULT_BLOCKED
|
||||||
|
&& $log->getIpAddress() === '203.0.113.10'
|
||||||
|
&& $log->getRequestPath() === '/login'
|
||||||
|
&& $metadata['requestCount'] === 101
|
||||||
|
&& $metadata['windowSeconds'] === 60;
|
||||||
|
}))
|
||||||
|
->willReturnArgument(0);
|
||||||
|
$event = \KTXF\Event\SecurityEvent::rateLimitExceeded(
|
||||||
|
'203.0.113.10',
|
||||||
|
101,
|
||||||
|
60,
|
||||||
|
'/login'
|
||||||
|
);
|
||||||
|
$event->setTenantId('tenant-a');
|
||||||
|
|
||||||
|
$this->service->logSecurityEvent($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[TestDox('Suspicious-activity events retain request and detection metadata')]
|
||||||
|
public function testSuspiciousActivityAudit(): void
|
||||||
|
{
|
||||||
|
$this->store->expects($this->once())
|
||||||
|
->method('createLog')
|
||||||
|
->with(self::callback(static function (FirewallLogObject $log): bool {
|
||||||
|
return $log->getEventType() === FirewallLogObject::EVENT_SUSPICIOUS
|
||||||
|
&& $log->getResult() === FirewallLogObject::RESULT_BLOCKED
|
||||||
|
&& $log->getIpAddress() === '203.0.113.20'
|
||||||
|
&& $log->getRequestPath() === '/admin'
|
||||||
|
&& $log->getRequestMethod() === 'POST'
|
||||||
|
&& $log->getMetadata()['detector'] === 'payload-signature';
|
||||||
|
}))
|
||||||
|
->willReturnArgument(0);
|
||||||
|
$event = \KTXF\Event\SecurityEvent::create(
|
||||||
|
\KTXF\Event\SecurityEvent::SUSPICIOUS_ACTIVITY,
|
||||||
|
'203.0.113.20',
|
||||||
|
null,
|
||||||
|
['detector' => 'payload-signature']
|
||||||
|
);
|
||||||
|
$event->setTenantId('tenant-a')
|
||||||
|
->setRequestPath('/admin')
|
||||||
|
->setRequestMethod('POST');
|
||||||
|
|
||||||
|
$this->service->logSecurityEvent($event);
|
||||||
|
}
|
||||||
|
|
||||||
#[TestDox('Typed tenant firewall settings drive brute-force thresholds')]
|
#[TestDox('Typed tenant firewall settings drive brute-force thresholds')]
|
||||||
public function testFirewallConfiguration(): void
|
public function testFirewallConfiguration(): void
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user