As of #299 we're using the client IP as a rate limit key and logic used to derive the client IP is 1. very basic and 2. assumes a proxy such as Cloudflare or Nginx by running through a list of headers and checking them all in sequence. This opens up the API to spoofing attacks if not running behind Cloudflare, Nginx or similar (basically, any proxy that sets one of "CF-Connecting-IP", "X-Real-IP", "True-Client-IP")
This lazy catch-all approach is not sustainable long-term and instead, operators need a way of customising the actual header (and perhaps logic, but that's more complex)
Essentially, if you were to attack an instance not running on Cloudflare, but set CF-Connecting-IP in the request headers to something random for each request, the rate limiter will not activate. This is because the fall-through to using the TCP connection IP is not triggered since it will find a CF-Connecting-IP header and use that.
I think a first pass approach would be to simply set a header config value CLIENT_IP_HEADER which is used to attempt to derive the client IP and failing that, fall back to the connecting TCP address. This way, operators can customise the header based on their setup whether it's open to the internet or behind any kind of proxy with a specific client IP header being set.
X-Forwarded-For is also an option, but I wouldn't trust it due to various XFF attack vectors plus it requires a bunch of logic to unpack the values (more on that here) and providing a way to customise this logic will be complex if done purely via key-value config. Perhaps something for #66 in future...
As of #299 we're using the client IP as a rate limit key and logic used to derive the client IP is 1. very basic and 2. assumes a proxy such as Cloudflare or Nginx by running through a list of headers and checking them all in sequence. This opens up the API to spoofing attacks if not running behind Cloudflare, Nginx or similar (basically, any proxy that sets one of "CF-Connecting-IP", "X-Real-IP", "True-Client-IP")
This lazy catch-all approach is not sustainable long-term and instead, operators need a way of customising the actual header (and perhaps logic, but that's more complex)
Essentially, if you were to attack an instance not running on Cloudflare, but set
CF-Connecting-IP
in the request headers to something random for each request, the rate limiter will not activate. This is because the fall-through to using the TCP connection IP is not triggered since it will find aCF-Connecting-IP
header and use that.I think a first pass approach would be to simply set a header config value
CLIENT_IP_HEADER
which is used to attempt to derive the client IP and failing that, fall back to the connecting TCP address. This way, operators can customise the header based on their setup whether it's open to the internet or behind any kind of proxy with a specific client IP header being set.X-Forwarded-For is also an option, but I wouldn't trust it due to various XFF attack vectors plus it requires a bunch of logic to unpack the values (more on that here) and providing a way to customise this logic will be complex if done purely via key-value config. Perhaps something for #66 in future...