benecaster_rate_limit_client_ip
Filters the IP address that every rate limit in the plugin counts against — the REST limiter, the episode search limit and the follower-signup throttle alike. Receives the value of REMOTE_ADDR, which may be ''.
X-Forwarded-For is NOT honoured by default, and must not be on a site with no proxy in front of it. Any client can send that header with any value, so trusting it turns every per-IP limit in the plugin into no limit at all — an attacker rotates the header and each request looks like a new visitor. That failure is silent: the limiter still appears to work, the counters still tick, and nothing surfaces to say the gate is open.
The filter exists because the safe default is wrong for a large minority of sites. Behind Cloudflare or any reverse proxy, REMOTE_ADDR is the proxy’s address, so every visitor shares one bucket and a per-IP limit silently becomes a site-wide one. A site in that position must opt in explicitly, and is responsible for reading a header its own proxy sets and overwrites.
One override affects every per-IP limit in the plugin, not just the form you were thinking about when you added it. That is deliberate — both consumers resolve the client IP the same way, so a proxy is configured once rather than half-applied.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$ip |
string |
— | The value of `REMOTE_ADDR`, possibly an empty string. |
Returns:
string
Examples
Read the real visitor IP behind Cloudflare
add_filter( 'benecaster_rate_limit_client_ip', function ( string $ip ): string {
// Only safe because THIS site's proxy sets and overwrites this header.
return isset( $_SERVER['HTTP_CF_CONNECTING_IP'] )
? (string) $_SERVER['HTTP_CF_CONNECTING_IP']
: $ip;
} );
Notes
This filter changes who counts as "one visitor" for rate-limiting purposes; it does not lift a limit or make an exception to one. Adding it does not set a precedent for putting a similar override in front of any other gate in the plugin.
The returned value is never echoed or queried — it is used only as input to RateLimitStore::hash(), which salts and truncates it before it becomes part of a transient key. Returning '' disables per-IP counting for that request.
Need this built rather than just documented? See our services →