First two search results for “blocking origin access directly” on Google showed me two misleading Cloudflare community threads, with wrong security assumption, which is why I decided to write this guide. [1] [2]
The best and recommended solution is using Authenticated Origin Pulls with custom certs per domain, but as this is not trivial to set up I decided write about the most simplest set up.
Attacker will find the leaked Origin IP / CNAME record your are pointing at
- SecurityTrails – Shows DNS history, if your domain pointed to a public IP before using Cloudflare, it might still be visible.
- ViewDNS.info – Lookup for historical A records and PTR records.
- DNSDumpster – Passive DNS and subdomain enumeration with IP history.
- Sometimes a dev subdomain (e.g. dev.javan.de) bypasses Cloudflare and points directly to the IP.
- Tools like Amass, Subfinder, or crt.sh (for TLS cert transparency logs) can enumerate these.
- If your domain uses SPF records that include your mail server IP, tools can extract these and cross-correlate with your web infrastructure.
Run the Bypass
The typical command you test your bypasses is:
curl -k https://<your-origin-ip> -H "Host: javan.de" -v
With that, you might think about adding SNI validation to your Ngnix, to block the above requests where the SNI doesn’t match your $host.
curl -k --resolve javan.de:<your-origin-ip> https://javan.de/ -v -H "Host: javan.de"
But even with such SNI validation the updated command would again work and make such validation useless. With the above command your Ngnix would both see the value “javan.de” for the SNI and for $host.
Talk about the Wrong mitigation
Many choose to allowlist the IP range of Cloudflare on their origin server. But as any attacker can run a request from the Cloudflare IP-range, as anyone can run Cloudflare workers, also with custom request headers and so on, he could fake those request to come from the Cloudflare network, even tho he would have bypasses CF WAF, CF Access etc.
Simplest Mitigation
Add a Cloudflare Worker / Transformer Rule which adds a cusom request header of your choice to the edge:
// Basic CF Worker snippet
export default {
async fetch(request, env, ctx) {
request = new Request(request, {
headers: {
...Object.fromEntries(request.headers),
"X-Origin-Secret": "s3cr3t-h3ad3r-v4lu3"
},
});
return fetch(request);
},
};
Validate it on your origin server in your Ngnix:
# Block if the secret header is missing or wrong
if ($http_x_origin_secret != "s3cr3t-h3ad3r-v4lu3") {
return 403;
}
Referenced Threads:
- [1] https://community.cloudflare.com/t/disabling-direct-access-to-origin-server-on-apache/489104/3
- [2] https://community.cloudflare.com/t/need-block-direct-access-by-ip-to-origin-server/524825/4