true]); $res = $this->call('POST', '/wp-login.php', ['log' => 'admin', 'pwd' => 'Hunter2!'], [], [], ['REMOTE_ADDR' => '203.0.113.77']); // Served the fake WordPress page (200), NOT a Laravel 419/405 that would unmask the framework. $res->assertStatus(200); $res->assertSee('WordPress', false); // The attacker's guessed credentials are logged as threat intel. $e = AuditEvent::where('action', 'security.honeypot_hit')->latest('id')->first(); $this->assertNotNull($e); $this->assertSame('admin', $e->meta['tried_user']); $this->assertSame('Hunter2!', $e->meta['tried_pass']); } public function test_phpmyadmin_and_generic_submits_are_trapped_not_405(): void { config(['clusev.honeypot.enabled' => true]); $this->call('POST', '/phpmyadmin', ['pma_username' => 'root', 'pma_password' => 'toor'], [], [], ['REMOTE_ADDR' => '203.0.113.80']) ->assertStatus(200); $this->assertSame('root', AuditEvent::where('action', 'security.honeypot_hit')->latest('id')->first()->meta['tried_user']); $this->call('POST', '/administrator', ['username' => 'sa', 'password' => 'pw'], [], [], ['REMOTE_ADDR' => '203.0.113.81']) ->assertStatus(200); $this->assertSame('sa', AuditEvent::where('action', 'security.honeypot_hit')->latest('id')->first()->meta['tried_user']); } public function test_banned_ip_stays_in_the_decoy_but_is_blocked_from_the_real_login(): void { config(['clusev.honeypot.enabled' => true]); // First hit from a non-exempt IP instant-bans it. $this->call('GET', '/wp-login.php', [], [], [], ['REMOTE_ADDR' => '203.0.113.79'])->assertStatus(200); $this->assertTrue(BannedIp::where('ip', '203.0.113.79')->exists()); // The now-banned prober still gets the fake decoy (BlockBannedIp is off for decoys) — kept inside // the deception, never told they're blocked. $this->call('GET', '/wp-login.php', [], [], [], ['REMOTE_ADDR' => '203.0.113.79'])->assertStatus(200); // …but the ban still keeps them off the REAL login (BlockBannedIp -> 403 for a banned guest). $this->call('GET', '/login', [], [], [], ['REMOTE_ADDR' => '203.0.113.79'])->assertStatus(403); } }