Anvil
Anvil - The mobile companion for Laravel Forge. Available now. Download for iOS

Suspicious Activity Detection

The package automatically detects suspicious authentication patterns and flags them for review.

Automatic Detection

Suspicious activity is automatically detected during login and failed login events. When detected, the authentication log is marked with is_suspicious = true and includes a reason.

Notifications

You can enable email, Slack, or SMS notifications when suspicious activity is detected. This feature is disabled by default.

Enabling Suspicious Activity Notifications

Add the following to your .env file:

1SUSPICIOUS_ACTIVITY_NOTIFICATION=true
2SUSPICIOUS_ACTIVITY_NOTIFICATION_RATE_LIMIT=3
3SUSPICIOUS_ACTIVITY_NOTIFICATION_RATE_LIMIT_DECAY=60

Or configure it directly in config/authentication-log.php:

1'notifications' => [
2 'suspicious-activity' => [
3 'enabled' => env('SUSPICIOUS_ACTIVITY_NOTIFICATION', false),
4 'location' => function_exists('geoip'),
5 'template' => \Rappasoft\LaravelAuthenticationLog\Notifications\SuspiciousActivity::class,
6 'rate_limit' => env('SUSPICIOUS_ACTIVITY_NOTIFICATION_RATE_LIMIT', 3),
7 'rate_limit_decay' => env('SUSPICIOUS_ACTIVITY_NOTIFICATION_RATE_LIMIT_DECAY', 60),
8 ],
9],

When enabled, users will receive notifications for all types of suspicious activity:

  • Multiple failed login attempts
  • Rapid location changes
  • Unusual login times (if enabled)

The notification includes details about the suspicious activity, login time, IP address, browser, and location (if available).

Detection Rules

Multiple Failed Logins

Detects when a user has multiple failed login attempts within a short time period:

1'suspicious' => [
2 'failed_login_threshold' => 5, // 5 failed logins in 1 hour triggers suspicious flag
3],

Rapid Location Changes

Detects when logins occur from multiple countries within a short time period (e.g., login from US, then UK within an hour).

Unusual Login Times

Detects logins outside of normal business hours (if enabled):

1'suspicious' => [
2 'check_unusual_times' => true,
3 'usual_hours' => [9, 10, 11, 12, 13, 14, 15, 16, 17], // 9 AM to 5 PM
4],

Manual Detection

You can manually check for suspicious activity:

1$user = User::find(1);
2$suspiciousActivities = $user->detectSuspiciousActivity();
3 
4// Returns array of suspicious activities:
5// [
6// [
7// 'type' => 'multiple_failed_logins',
8// 'count' => 5,
9// 'message' => '5 failed login attempts in the last hour'
10// ],
11// [
12// 'type' => 'rapid_location_change',
13// 'countries' => ['US', 'UK'],
14// 'message' => 'Login from multiple countries within an hour'
15// ],
16// [
17// 'type' => 'unusual_login_time',
18// 'hour' => 3,
19// 'message' => 'Login at unusual time: 3:00'
20// ]
21// ]

Marking Logs as Suspicious

Manually mark a log as suspicious:

1$log = AuthenticationLog::find(1);
2$log->markAsSuspicious('Manual review: Unusual pattern detected');

Querying Suspicious Logs

1use Rappasoft\LaravelAuthenticationLog\Models\AuthenticationLog;
2 
3// Get all suspicious logs
4$suspiciousLogs = AuthenticationLog::suspicious()->get();
5 
6// Get suspicious logs for a user
7$userSuspiciousLogs = AuthenticationLog::forUser($user)->suspicious()->get();
8 
9// Get recent suspicious activities
10$recentSuspicious = AuthenticationLog::suspicious()->recent(7)->get();

Example: Suspicious Activity Alert

1// In your LoginController or similar
2public function login(Request $request)
3{
4 // ... authentication logic ...
5 
6 $user = auth()->user();
7 $suspicious = $user->detectSuspiciousActivity();
8 
9 if (!empty($suspicious)) {
10 // Log suspicious activity
11 \Log::warning('Suspicious activity detected', [
12 'user_id' => $user->id,
13 'activities' => $suspicious,
14 ]);
15 
16 // Optionally require additional verification
17 // return redirect()->route('verify-suspicious-login');
18 }
19 
20 return redirect()->intended();
21}

Getting Suspicious Activity Count

1$user = User::find(1);
2$suspiciousCount = $user->getSuspiciousActivitiesCount();