TLDR
Any time a country block is used in a Dockflare access policy, the tunnel will be open to any non-blocked country, regardless of other restrictions (email, IP, etc).
Issue
When dockflare creates an Access Policy that includes Blocked Countries those countries are passed to the backend and eventually end up in the _parse_and_build_policy_from_form function. If countries are defined here, a new policy is appended to the policy array with a bypass decision.
The Cloudflare Zero Trust Documentation on Bypass rules has a large warning about using this decision.
The key part of this warning is When making Bypass policies, you will not be able to apply certain identity-based selectors (such as email).
Thus, if a user creates a policy that both restricts users to a list of emails AND enables "Blocked Countries" dockflare acts in a way the user does not expect. It allows any user from a non-blocked country to access the application, bypassing the "Allowed Emails or Domains" the user had set. This is not what a user expects, and I believe it is a security issue, as users will expose applications they thought were restricted to specified users to entire countries.
Test/Proof of claim
To test this, I created the following policy:
The 1 country allowed is the US (I clicked Allow US Only). Note that this rule should restrict the application to users with *@badsectorlabs.com email addresses.
I configured httpbin with the following docker compose file:
services:
httpbin:
image: kennethreitz/httpbin
container_name: httpbin
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "500k"
max-file: "1"
networks:
- cloudflare-net
labels:
- "dockflare.enable=true"
- "dockflare.hostname=httpbin.badsectorlabs.com"
- "dockflare.service=http://httpbin:80"
- "dockflare.access.group=bsl-users"
networks:
cloudflare-net:
name: cloudflare-net
external: true
The tunnel was created successfully:
And it shows in Cloudflare Zero Trust:
The critical warning is Note: Access will evaluate policies with Bypass and Service Auth actions first. Then, policies are evaluated in top-to-bottom order. Thus, the bypass rule is not after the Allow defined users but actually the first to evaluate, and if it hits, it will stop processing any further rules. Thus if you an a US IP address, you can access https://httpbin.badsectorlabs.com despite the Allow defined users rule.
Despite curl not having any cloudflare auth, I can curl httpbin and get a response from a US IP address:
$ curl -v https://httpbin.badsectorlabs.com/get
* Host httpbin.badsectorlabs.com:443 was resolved.
---8K----SSL info cut-----8K-----
> GET /get HTTP/2
> Host: httpbin.badsectorlabs.com
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
< date: Tue, 30 Sep 2025 23:36:19 GMT
< content-type: application/json
< content-length: 539
< access-control-allow-credentials: true
< access-control-allow-origin: *
< server: cloudflare
< cf-cache-status: DYNAMIC
< nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
< report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=1n7Bz%2B0rkRxD4XN0651t4vw2rqzGK9yIXQLsEi3w7tg8xWS5V4TuEEhJn6EhVuPfRY7qgDLW4i9U6AY0c9aMbw6mGNYQNJhXUMfy1dOjGVEbATdjHyIY"}]}
< cf-ray: 98778ab33e08f13a-ORD
< alt-svc: h3=":443"; ma=86400
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, br",
"Cdn-Loop": "cloudflare; loops=1",
"Cf-Connecting-Ip": "[REDACTED US IP ADDRESS]",
"Cf-Ipcountry": "US",
"Cf-Ray": "98778ab33e08f13a-ORD",
"Cf-Visitor": "{\"scheme\":\"https\"}",
"Cf-Warp-Tag-Id": "6720234c-698c-4e1e-bf0e-99d7a24b95b4",
"Connection": "keep-alive",
"Host": "httpbin.badsectorlabs.com",
"User-Agent": "curl/8.7.1"
},
"origin": "[REDACTED US IP ADDRESS]",
"url": "https://httpbin.badsectorlabs.com/get"
}
* Connection #0 to host httpbin.badsectorlabs.com left intact
According to git blame this has been an issue since 2.1.4: https://github.com/ChrispyBacon-dev/DockFlare/blame/stable/dockflare/app/web/routes.py#L1682
Mitigation
Removing Blocked Countries from an access policy enforces the emails/domain/IP restrictions as expected.
Suggested Fix
Simply change the policy from bypass to block. Review other uses of bypass such as the defined IP policy, and carefully document the effect if bypass is intended (i.e. any traffic from that IP is allowed, regardless of other policy elements like allowed emails).
Thanks
Dockflare is a very useful application. Thank you for creating and maintaining it!
TLDR
Any time a country block is used in a Dockflare access policy, the tunnel will be open to any non-blocked country, regardless of other restrictions (email, IP, etc).
Issue
When dockflare creates an Access Policy that includes
Blocked Countriesthose countries are passed to the backend and eventually end up in the _parse_and_build_policy_from_form function. If countries are defined here, a new policy is appended to the policy array with abypassdecision.The Cloudflare Zero Trust Documentation on Bypass rules has a large warning about using this decision.
The key part of this warning is
When making Bypass policies, you will not be able to apply certain identity-based selectors (such as email).Thus, if a user creates a policy that both restricts users to a list of emails AND enables "Blocked Countries" dockflare acts in a way the user does not expect. It allows any user from a non-blocked country to access the application, bypassing the "Allowed Emails or Domains" the user had set. This is not what a user expects, and I believe it is a security issue, as users will expose applications they thought were restricted to specified users to entire countries.
Test/Proof of claim
To test this, I created the following policy:
The
1 country allowedis the US (I clickedAllow US Only). Note that this rule should restrict the application to users with*@badsectorlabs.comemail addresses.I configured
httpbinwith the following docker compose file:The tunnel was created successfully:
And it shows in Cloudflare Zero Trust:
The critical warning is
Note: Access will evaluate policies with Bypass and Service Auth actions first. Then, policies are evaluated in top-to-bottom order.Thus, the bypass rule is not after theAllow defined usersbut actually the first to evaluate, and if it hits, it will stop processing any further rules. Thus if you an a US IP address, you can access https://httpbin.badsectorlabs.com despite theAllow defined usersrule.Despite
curlnot having any cloudflare auth, I can curl httpbin and get a response from a US IP address:According to git blame this has been an issue since 2.1.4: https://github.com/ChrispyBacon-dev/DockFlare/blame/stable/dockflare/app/web/routes.py#L1682
Mitigation
Removing
Blocked Countriesfrom an access policy enforces the emails/domain/IP restrictions as expected.Suggested Fix
Simply change the policy from
bypasstoblock. Review other uses ofbypasssuch as the defined IP policy, and carefully document the effect ifbypassis intended (i.e. any traffic from that IP is allowed, regardless of other policy elements like allowed emails).Thanks
Dockflare is a very useful application. Thank you for creating and maintaining it!