Priority P1. Source-confirmed follow-up separated from WebDecoy/app#875; this is WordPress SDK work, not a transport change to the standalone sensor.
sdk/src/BotDetector.php falls back to getClientIP() when supplied signals lack ip_address. That private resolver accepts CF-Connecting-IP, X-Forwarded-For, and X-Real-IP without establishing a trusted proxy, and takes the leftmost XFF value. SignalCollector already owns the trusted-proxy-aware resolution contract.
Use the canonical resolver when collecting missing IP evidence; preserve explicitly supplied valid request context. Remove the second resolver without reintroducing cURL into the plugin. Missing context must remain unknown or use the trusted socket context, never trust caller-controlled forwarded headers by default.
Acceptance: real behavior tests cover no proxy trust, spoofed forwarded headers, configured trusted proxies, IPv4/IPv6 chains, and the missing-ip BotDetector path. Both entry points resolve the same request identically. Run the existing relevant plugin checks. Link implementation and any compatibility note back to WebDecoy/app#875.
Priority P1. Source-confirmed follow-up separated from WebDecoy/app#875; this is WordPress SDK work, not a transport change to the standalone sensor.
sdk/src/BotDetector.phpfalls back togetClientIP()when supplied signals lackip_address. That private resolver accepts CF-Connecting-IP, X-Forwarded-For, and X-Real-IP without establishing a trusted proxy, and takes the leftmost XFF value.SignalCollectoralready owns the trusted-proxy-aware resolution contract.Use the canonical resolver when collecting missing IP evidence; preserve explicitly supplied valid request context. Remove the second resolver without reintroducing cURL into the plugin. Missing context must remain unknown or use the trusted socket context, never trust caller-controlled forwarded headers by default.
Acceptance: real behavior tests cover no proxy trust, spoofed forwarded headers, configured trusted proxies, IPv4/IPv6 chains, and the missing-ip BotDetector path. Both entry points resolve the same request identically. Run the existing relevant plugin checks. Link implementation and any compatibility note back to WebDecoy/app#875.