Findings · 2026-10-14 · By VSNARY | Emmanuel Orta · 0 views
Cloudflare Access on one path locked our customers out
We put our owner pages behind Cloudflare Access on 14 October. The rule for /login also covered the customer sign-in, which lived at the same address. For about an hour, every Sign in link on 247 pages opened a code form only two people could pass.
At 10:56 AM MDT on 14 October 2026 CrawlCheck put its owner pages behind Cloudflare Access, including /login. Customer sign-in also lived at /login, so the rule covered it, and every Sign in link on the site (247 pages) opened a one-time-code form that only the two owner email addresses could pass. Access covered everything under the path: /login/email and /login/magic were gated, while /loginx was not. A link sweep found it; at 11:56 AM customer sign-in moved to /signin, and every link, redirect, form and sign-in email moved with it. /login is now the owners' door only.
Cloudflare Access puts a login in front of chosen paths of a website before a request ever reaches the site. We use it to protect the pages only the site's owners should see. On 14 October 2026 we turned it on, and for an hour it also locked out the people who pay us.
Why put Access in front at all #
The owner panel already had its own sign-in. Access adds a second check that runs at Cloudflare's edge, before a request reaches any of our code. If our own sign-in ever had a flaw, the panel would still be behind a wall we did not write. The trade-off is that Access is blunt by design: it decides by path, and it knows nothing about who a page is meant for. Whatever lives under a protected path is protected, whether it should be or not.
What we did #
At 10:56 AM Mountain Time we created an Access application on crawlcheck.io for three paths: /admin*, /owner* and /login. The policy allows two email addresses, each proving itself with a one-time code sent by email. The intent was to put the owner panel behind a second wall, in addition to its own sign-in.
What it also did #
Customers signed in at /login too: the page with the sign-in form, /login/email where the form sends a request for a sign-in link, and /login/magic where that emailed link lands. The owners' sign-in and the customers' sign-in shared one address. From 10:56 AM, a customer who clicked Sign in reached a Cloudflare page asking for an email address it would never accept.
We tested the rule's reach afterwards, signed out, from outside our network:
| Path | Signed-out response | Covered by the /login rule? |
|---|---|---|
/login | 302 to the Access login page | Yes |
/login/email | 302 to the Access login page | Yes |
/login/magic | 302 to the Access login page | Yes |
/loginx | 404 from the site itself | No |
A path rule covers that path and everything below it, not every address that starts with the same letters. Cloudflare's documentation on application paths describes the inheritance: when no more specific rule exists, a deeper path takes the rules of its parent. That is the right behaviour, and it is exactly what caught our customer pages.
How we found it #
Not from a customer. That morning we were crawling the whole site before rebuilding it: every page in the sitemap and all 4,433 internal links. A link that answers with a redirect to another company's login page stands out in that kind of sweep, and 247 pages carried one, the Sign in link in the site's header. The sweep finished just before noon.
The fix #
At 11:56 AM we gave customers their own door and left the owners' door where it was:
| Purpose | Before | After 11:56 AM |
|---|---|---|
| Customer sign-in page | /login | /signin |
| Request a sign-in link | /login/email | /signin/email |
| Open the emailed link | /login/magic | /signin/magic |
| Owners' sign-in | /login | /login, behind Access |
Every customer-facing link, redirect and form action moved, and so did the address inside the sign-in email. The translated pages moved with them: the German header link reads Anmelden and opens /signin. We checked by outcome: /signin answers 200 with both forms, a request with a bad key is refused with 401, and no customer page links to /login any more.
Who it affected #
Anyone who tried to sign in as a customer between 10:56 and 11:56 AM Mountain Time. Sign-in links expire after 15 minutes and work once, so no link emailed before the change could still be waiting in an inbox afterwards. A customer with a bookmark to /login will still reach the owners' code form; the customer sign-in is at /signin. Licence keys, reports and data were never exposed: the failure only refused access, it did not grant any.
What to check before gating a path #
- List every route under the path, including the ones a form posts to and the ones an email links to. Those are the easiest to forget, because no page links to them.
- Give staff and customers different addresses. A shared sign-in page means any wall in front of one is a wall in front of both.
- Fetch your own site signed out after any access change, every page and every link. A redirect to another domain's login page from a public link is the signal.
- Prefer a specific path to a short one.
/admin*was safe because nothing public lives under it;/loginwas not.
This is one of the corrections we publish when CrawlCheck itself was wrong. All of them are listed together.
Every figure above came out of CrawlCheck.
Point it at your own domain and see the same measurements, free.
The main product
Found this on your own site? We fix it for $749.
Scan free to see where you stand. The fix is one site, every finding implemented and re-measured, with a sealed before and after.
Questions this post answers
Does a Cloudflare Access path rule cover subpaths?
In our test, yes: an application path of /login also gated /login/email and /login/magic, while /loginx, a different path that only shares the prefix, reached the site normally. Cloudflare's documentation says a deeper path inherits its parent's rules when no more specific rule exists.
Why did CrawlCheck customers see a Cloudflare login page?
For about an hour on 14 October 2026, from 10:56 to 11:56 AM MDT, the customer sign-in at /login sat behind a Cloudflare Access rule meant for the site's owners. Customer sign-in moved to /signin.
Where do I sign in to CrawlCheck?
At crawlcheck.io/signin. The /login address is the owners' sign-in and is behind Cloudflare Access.
Was any customer data exposed?
No. The failure only refused access to the sign-in page; it did not grant access to anything. Reports, licence keys and data were unaffected.
How do I avoid gating customer pages with Cloudflare Access?
List every route under each path you protect, including form targets and links sent by email, keep staff and customer sign-in on different paths, and fetch your whole site signed out after any access change.
Related findings
Comments
Comments are read before they appear. Nothing is published automatically, and no account is needed.
Writing about this? Facts, live figures and marks — every number on that page is dated and traceable to a scan.