Skip to content

Protection against Cloudflare header CF‐Connecting‐IP Spoofing

Conor McKnight edited this page Sep 26, 2025 · 2 revisions

So smart attackers will send this header to trick the server into using a fake / spoofed IP address and you should NOT trust this header without checking the IP address that sent it first.

For example

curl.exe "http://localhost/" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" -H "Accept-Language: en-GB,en;q=0.5" -H "Accept-Encoding: gzip, deflate, br, zstd" -H "DNT: 1" -H "Connection: keep-alive" -H "Cookie: name1=1; name2=2; logged_in=1" -H "Upgrade-Insecure-Requests: 1" -H "Sec-Fetch-Dest: document" -H "Sec-Fetch-Mode: navigate" -H "Sec-Fetch-Site: none" -H "Sec-Fetch-User: ?1" -H "Priority: u=0, i" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "User-Agent:testagent1" -H "CF-Connecting-IP: 1" -H "X-Forwarded-For: 1"

The server will think your IP address is "1" because of -H "CF-Connecting-IP: 1"

All the attacker will do with every request they hit your server with is change the CF-Connecting-IP header they send you to bypass any flood limits.

By checking the header against the whitelist of IP's allowed to use that header will protect you from these kinds of DDoS attacks.

https://github.com/C0nw0nk/Nginx-Lua-Anti-DDoS/blob/master/lua/anti_ddos_challenge.lua#L1417

--[[
Security feature to prevent spoofing on the Proxy headers CF-Connecting-IP or X-forwarded-for user-agent.
For example a smart DDoS attack will send a fake CF-Connecting-IP header or X-Forwarded-For header in their request
They do this to see if your server will use their real ip or the fake header they provide to you most servers do not even check this I do :)
Add your ip ranges to the list of who you expect to send you a proxy header.
Example to test with : curl.exe "http://localhost/" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" -H "Accept-Language: en-GB,en;q=0.5" -H "Accept-Encoding: gzip, deflate, br, zstd" -H "DNT: 1" -H "Connection: keep-alive" -H "Cookie: name1=1; name2=2; logged_in=1" -H "Upgrade-Insecure-Requests: 1" -H "Sec-Fetch-Dest: document" -H "Sec-Fetch-Mode: navigate" -H "Sec-Fetch-Site: none" -H "Sec-Fetch-User: ?1" -H "Priority: u=0, i" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "User-Agent:testagent1" -H "CF-Connecting-IP: 1" -H "X-Forwarded-For: 1"
]]
localized.proxy_header_table = {
"10.0.0.0/8", --localnetwork
"172.16.0.0/12", --localnetwork
"127.0.0.0/16", --localhost
"192.168.0.0/16", --localhost
--Cloudflare IP's https://www.cloudflare.com/en-gb/ips/
"173.245.48.0/20","103.21.244.0/22","103.22.200.0/22","103.31.4.0/22","141.101.64.0/18","108.162.192.0/18","190.93.240.0/20","188.114.96.0/20","197.234.240.0/22","198.41.128.0/17","162.158.0.0/15","104.16.0.0/13","104.24.0.0/14","172.64.0.0/13","131.0.72.0/22","2400:cb00::/32","2606:4700::/32","2803:f800::/32","2405:b500::/32","2405:8100::/32","2a06:98c0::/29","2c0f:f248::/32",
}

Only Cloudflare and Local host / local network IP ranges are trusted to pass this header to nginx anyone else who sends these headers are not trusted and will be blocked.

Clone this wiki locally