-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Validation Result: Confirmed Bug
Verdict: VALID_BUG | Confidence: HIGH | Severity: Medium
Related: wp.org support thread — Behind Proxy
Summary
Confirmed: behind Cloudflare, the country flag can show the Cloudflare data center's country instead of the visitor's real country. Two root causes identified in the codebase.
Root Cause
Fault Location 1: src/Tracker/Utils.php:133
Mechanism: The IP detection function does not check HTTP_CF_CONNECTING_IP (Cloudflare's primary header for the real client IP). Only standard proxy headers like HTTP_X_FORWARDED_FOR are checked.
Fault Location 2: src/Tracker/Processor.php:241
Mechanism: The tracking pipeline hardcodes provider selection as maxmind or dbip, ignoring the geolocation_provider admin setting. The Cloudflare geolocation provider (which reads HTTP_CF_IPCOUNTRY directly from Cloudflare headers) exists but is never invoked during tracking.
Causal Chain:
- Visitor behind Cloudflare →
REMOTE_ADDRis CF edge IP getRemoteIp()may not detect real IP (missing CF-Connecting-IP header)- Even if detected, geolocation IP priority logic can be inverted when server restores real IP via mod_remoteip
- Cloudflare geolocation provider (which bypasses IP lookup entirely using CF headers) is unreachable in tracking pipeline
- Result: geolocation resolves to CF data center country for all visitors
Workaround (Available Now)
Use the slimstat_filter_ip_address filter to prioritize HTTP_CF_CONNECTING_IP:
add_filter('slimstat_filter_ip_address', function($ipArray) {
if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$cfIp = filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP);
if ($cfIp) {
$ipArray[1] = $ipArray[0]; // Move REMOTE_ADDR to other_ip
$ipArray[0] = $cfIp; // Set real IP as primary
}
}
return $ipArray;
});Code References
| File | Lines | Description |
|---|---|---|
src/Tracker/Utils.php |
125-148 | IP detection — missing CF-Connecting-IP |
src/Tracker/Processor.php |
69 | Geolocation IP selection logic |
src/Tracker/Processor.php |
241 | Hardcoded provider selection (ignores CF) |
src/Services/Geolocation/Provider/CloudflareGeolocationProvider.php |
1-92 | Cloudflare provider (dead code in tracker) |
admin/config/index.php |
281-290 | Admin UI offers Cloudflare option |
Validated via qa-issue-validate skill (jaan.to plugin)