Log mislukte logins als LOGIN_FAILED (fail2ban/rapportage), logger-threshold naar 5

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 10:21:08 +02:00
co-authored by Claude Sonnet 5.5
parent 506c88a5bd
commit 643f5fd9a7
7 changed files with 188 additions and 1 deletions
+23
View File
@@ -24,6 +24,8 @@ class Login extends BaseController
$user = \User::where('username', $username)->first();
if (!$user) {
$this->logLoginFailed($username);
return $this->json(false);
}
@@ -69,6 +71,8 @@ class Login extends BaseController
]);
}
$this->logLoginFailed($username);
return $this->json($passwordCheck);
}
@@ -169,6 +173,8 @@ class Login extends BaseController
'message' => 'Succesvol geverifieerd'
]);
} else {
$this->logLoginFailed($user->username ?: $userId . ':2fa');
return $this->json([
'success' => false,
'message' => 'Ongeldige verificatiecode'
@@ -308,4 +314,21 @@ class Login extends BaseController
return false;
}
/**
* Log a rejected password or 2FA code in the format parsed by the
* fail2ban jail `app-login` and the security report collector:
* "LOGIN_FAILED user=<name> ip=<ip>". Never log the password or OTP.
*
* The IP is the real client IP only while the app runs directly behind
* Apache. If Config\App::$proxyIPs is ever set, getIPAddress() resolves
* the forwarded client IP and keeps this correct.
*/
private function logLoginFailed(string $user): void
{
log_message('warning', 'LOGIN_FAILED user={user} ip={ip}', [
'user' => sanitize_log_user($user),
'ip' => $this->request->getIPAddress(),
]);
}
}