fix(api): use the Cloudflare client IP for allowed IPs and audit logs

Closes #12301

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-10-25 23:47:39 +01:00
co-authored by Claude Opus 5.5
parent 0f0a1e920d
commit 80ce0efe7e
12 changed files with 77 additions and 23 deletions
+2 -2
View File
@@ -28,7 +28,7 @@ if (! function_exists('auditLog')) {
$token = $user?->currentAccessToken();
$payload = AuditEvent::redactContext(array_merge([
'event' => $event,
'ip' => $request?->ip(),
'ip' => $request ? (client_ip($request) ?: null) : null,
'ua' => substr((string) $request?->userAgent(), 0, 200),
'user_id' => $user?->id,
'user_email' => $user?->email,
@@ -102,7 +102,7 @@ if (! function_exists('shouldRecordAuditEvent')) {
$request = app()->bound('request') ? request() : null;
$fingerprint = hash('sha256', json_encode([
$event,
$request?->ip(),
$request ? client_ip($request) : null,
data_get($context, 'reason'),
data_get($context, 'server_uuid'),
Str::lower(trim((string) data_get($context, 'attempted_email'))),
+10 -3
View File
@@ -2,13 +2,20 @@
use Illuminate\Http\Request;
function auth_rate_limit_ip(Request $request): string
/**
* The client IP for rate limits, allow-lists, and audit logs. Behind Cloudflare, $request->ip()
* is the Cloudflare edge, so a valid CF-Connecting-IP is used: on cloud, and on self-hosted
* instances when the request comes from a Cloudflare IP. A client that connects directly
* cannot set the client IP with the header.
*/
function client_ip(Request $request): string
{
$ip = (string) $request->ip();
$cloudflareIp = $request->header('CF-Connecting-IP');
if (isCloud() && is_string($cloudflareIp) && filter_var($cloudflareIp, FILTER_VALIDATE_IP) !== false) {
if (is_string($cloudflareIp) && filter_var($cloudflareIp, FILTER_VALIDATE_IP) !== false && (isCloud() || isCloudflareIp($ip))) {
return $cloudflareIp;
}
return (string) $request->ip();
return $ip;
}
+1 -1
View File
@@ -2448,7 +2448,7 @@ function isCloudflareIp(string $ip): bool
$cloudflareIps = [
'173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22', '103.31.4.0/22',
'141.101.64.0/18', '108.162.192.0/18', '190.93.240.0/20', '188.114.96.0/20',
'197.234.240.0/22', '198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/13',
'197.234.240.0/22', '198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/13', '104.24.0.0/14',
'172.64.0.0/13', '131.0.72.0/22', '2400:cb00::/32', '2606:4700::/32',
'2803:f800::/32', '2405:b500::/32', '2405:8100::/32', '2a06:98c0::/29',
'2c0f:f248::/32',