You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, CodeIgniter Shield uses $this->request->getIPAddress() throughout its codebase, which doesn't correctly detect the real client IP when the application is behind reverse proxies (Nginx, Cloudflare, load balancers, CDNs, etc.).
Proposed Solution:
Replace all instances of $this->request->getIPAddress() with a helper function that:
Checks trusted proxy headers in order of preference (X-Forwarded-For, X-Real-IP, CF-Connecting-IP, etc.)
Validates IPs and filters out private/reserved addresses for security
Falls back to REMOTE_ADDR when no proxy headers are present
Optionally allows configuration of which headers to trust
This would make Shield production-ready for modern deployment architectures where applications commonly sit behind proxies.
Example Implementation:
if (!function_exists('shield_get_real_ip')) {
/** * Get real client IP address with reverse proxy support. * Checks trusted proxy headers in order of preference. * * @return string */functionshield_get_real_ip(): string
{
$request = service('request');
// Ordered by trustworthiness$proxyHeaders = [
'HTTP_CF_CONNECTING_IP', // Cloudflare'HTTP_TRUE_CLIENT_IP', // Akamai, Cloudflare Enterprise'HTTP_X_REAL_IP', // Nginx proxy'HTTP_X_FORWARDED_FOR', // Standard proxy header'HTTP_X_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED', // RFC 7239'HTTP_CLIENT_IP',
'REMOTE_ADDR', // Direct connection fallback
];
foreach ($proxyHeadersas$header) {
$value = $request->getServer($header);
if (empty($value)) {
continue;
}
// X-Forwarded-For may contain comma-separated IPs (client, proxy1, proxy2)// Take the rightmost public IP$ips = array_reverse(array_map('trim', explode(',', (string)$value)));
foreach ($ipsas$ip) {
// Validate and ensure it's publicif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
return$ip;
}
}
}
return$request->getIPAddress() ?? '0.0.0.0';
}
}
Files to Update (examples):
Controllers/MagicLinkController.php
Controllers/LoginController.php
Models/LoginModel.php
Any other file using $this->request->getIPAddress()
Benefits:
Accurate IP logging for rate limiting, security audits, and analytics
Works correctly with Cloudflare, AWS ELB, Nginx, Apache proxies
Prevents IP spoofing via private/reserved address filtering
Maintains backward compatibility (falls back to REMOTE_ADDR)
Sample
replace:
$this->request->getIPAddress(),
with:
shield_get_real_ip(),
Or inline until Shield adopts it:
privatefunctionrecordLoginAttempt(
string$identifier,
bool$success,
$userId = null,
): void {
/** @var LoginModel $loginModel */$loginModel = model(LoginModel::class);
$loginModel->recordLoginAttempt(
Session::ID_TYPE_MAGIC_LINK,
$identifier,
$success,
$this->getRealClientIP(), // Changed here
(string) $this->request->getUserAgent(),
$userId,
);
}
/** * Get real client IP with proxy support. */privatefunctiongetRealClientIP(): string
{
returnshield_get_real_ip(),;
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Feature Request for CodeIgniter Shield
Description:
Currently, CodeIgniter Shield uses
$this->request->getIPAddress()throughout its codebase, which doesn't correctly detect the real client IP when the application is behind reverse proxies (Nginx, Cloudflare, load balancers, CDNs, etc.).Proposed Solution:
Replace all instances of
$this->request->getIPAddress()with a helper function that:X-Forwarded-For,X-Real-IP,CF-Connecting-IP, etc.)REMOTE_ADDRwhen no proxy headers are presentThis would make Shield production-ready for modern deployment architectures where applications commonly sit behind proxies.
Example Implementation:
Files to Update (examples):
Controllers/MagicLinkController.phpControllers/LoginController.phpModels/LoginModel.php$this->request->getIPAddress()Benefits:
REMOTE_ADDR)Sample
replace:
with:
shield_get_real_ip(),Or inline until Shield adopts it:
Beta Was this translation helpful? Give feedback.
All reactions