Cloudflare Tunnel: public hostnames with no Access policy, leaked tunnel tokens, and origins still port-forwarded
Risk / Filed 28 Sep 2026
cloudflare-tunnelcloudflare-accessproxmoxportainergrafanacomposerouter
What: A tunnel only moves traffic. It does not add a login. Cloudflare's own docs say it plainly:
"If you do not have an Access application in place, the published application will be available to
anyone on the Internet." Three mistakes keep showing up in labs. You publish Proxmox, Portainer or
Grafana through a tunnel with no Access policy. You commit the tunnel token to a public repo or
compose file, and "Anyone with the token can run the tunnel." Or you leave the old port-forward
open, so the origin can still be reached without going through Cloudflare. A separate issue:
throwaway *.trycloudflare.com Quick Tunnels are a documented malware delivery channel. Proofpoint
has tracked it since February 2024, Securonix reported SERPENTINE#CLOUD in June 2025, and Cofense
reported a 2025 peak in March 2026.
Who it hits:
-
Any public hostname on your tunnel that has no matching Access application. This is worst for admin UIs: Proxmox (8006), Portainer (9443/9000) and Grafana (3000). Their own login page becomes the only thing between the internet and your hypervisor or Docker socket.
-
TUNNEL_TOKEN=eyJ...ortunnel run --token eyJ...in adocker-compose.yml,.env, or Ansible file that has ever been pushed to GitHub or a public Gitea/Forgejo, including git history. Anyone holding it can run a connector for your tunnel and take a share of your traffic. -
Routers that still forward 443, 8006 or 9443 to the box after you moved to a tunnel, and UPnP mappings too. Your Access policy does nothing on that path.
-
Anyone using
cloudflared tunnel --url ...Quick Tunnels to "just share something". Cloudflare says they are "intended for testing and development only."
Check if you're affected:
# 1. For EVERY hostname in Zero Trust > Networks > Tunnels > <tunnel> > Public hostnames:
# open it in a private window. You must see a Cloudflare Access login, not the app.
# Scripted version: a protected host answers with a redirect to <team>.cloudflareaccess.com.
for h in proxmox.example.com portainer.example.com grafana.example.com; do
printf '%s -> ' "$h"
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' "https://$h/"
done
# 200, or a redirect to the app's own /login = NOT protected by Access
# 2. Tunnel tokens in files and in git history (tokens start with eyJhIjoi)
grep -rEn 'TUNNEL_TOKEN|--token[ =]|eyJhIjoi' ~/ --include='*.yml' --include='*.yaml' \
--include='*.env' --include='.env' --include='*.sh' 2>/dev/null
for r in $(find ~ -name .git -type d -prune 2>/dev/null); do
git -C "${r%/.git}" log -p --all 2>/dev/null | grep -q 'eyJhIjoi' && echo "TOKEN IN HISTORY: ${r%/.git}"
done
# 3. Is the origin reachable directly? Run this from OUTSIDE your LAN (phone hotspot):
nmap -Pn -p 22,80,443,3000,8006,9000,9443 <your-WAN-IP>
# Any "open" port is bypassing the tunnel. Also check the router's port-forward and UPnP pages.
# 4. Stray cloudflared / quick tunnels on your boxes
pgrep -a cloudflared; docker ps --format '{{.Names}} {{.Image}}' | grep -i cloudflared
# Any "--url" / trycloudflare process you don't recognise = investigate.
Do this:
-
Put Access in front of every admin hostname. Go to Zero Trust > Access controls > Applications > Create new application > Self-hosted, and add the public hostname. Attach an Allow policy for your own email or IdP group only. Access is deny by default, so anyone not matched gets nothing. Do this before you add new tunnel routes, not after.
-
If a token was ever public, rotate it and kill live connectors. In the dashboard, go to Networking > Tunnels > your tunnel > Refresh token. Some doc pages call the button "Rotate token". Then reinstall/restart
cloudflaredeverywhere with the new token. Refreshing blocks new connections with the old token, but existing connectors stay up until restarted. That includes one an attacker is running. Drop them all:curl -X DELETE "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/cfd_tunnel/$TUNNEL_ID/connections" -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Then check the tunnel's Connectors list shows only your hosts. -
Get the token out of compose. On cloudflared 2025.4.0 or newer, use
--token-file/TUNNEL_TOKEN_FILEpointing at a file that is not tracked by git, or keepTUNNEL_TOKENin a gitignored.env. Scrubbing git history does not un-leak a token. Rotate it anyway. -
Close the side door. Delete every router port-forward to the tunnelled services and turn off UPnP.
cloudflaredonly makes outbound connections, so the host needs no inbound ports at all. Firewall inbound to deny. -
Don't use Quick Tunnels for anything real. If nothing in your lab uses them, add
trycloudflare.comto a Pi-hole/AdGuard blocklist, or at least alert on it. On a lab network, a lookup for it usually means malware staging or someone's test tunnel you forgot about. -
Verify. Re-run checks 1–3. Every admin host should redirect to
cloudflareaccess.com, grep should come back empty, and the outside nmap should show all ports filtered/closed.
Why this level: Reachable, common and high blast radius: a Proxmox or Portainer panel is the hypervisor or the Docker socket. That is 3 yes answers, so this-week. It is not higher because the app's own login still stands in the way, and no documented campaign (as of 2026-09-28) targets unprotected lab tunnel hostnames. The Quick Tunnel abuse is real but targets phishing victims, not your tunnel. If you run Portainer/Proxmox with default or reused creds behind an unprotected hostname, treat it as act-tonight.
Sources
- Cloudflare docs: Publish a self-hosted application (Access)
- Cloudflare docs: Tunnel tokens
- Cloudflare docs: Tunnel permissions (token refresh, delete connections)
- Cloudflare docs: Tunnel run parameters (--token, TUNNEL_TOKEN, --token-file)
- Cloudflare docs: Cloudflare Tunnel overview (outbound-only, block inbound)
- Cloudflare docs: Quick Tunnels (TryCloudflare)
- Proofpoint (2024-08-01): Threat actor abuses Cloudflare Tunnels to deliver RATs
- Securonix (2025-06-18): SERPENTINE#CLOUD abuses Cloudflare Tunnels
- Cofense (2026-03-25): How Cloudflare services are abused for credential theft and malware
How severity is decided. Source file: risks/2026-09-28-cloudflare-tunnel-exposure-mistakes.md.