Expo dev server tunnel missing authentication boundary for local development URLs
0 reputation · 22 Jan 2024, 09:20 UTC
0 reputation · 22 Jan 2024, 09:20 UTC
Expo's expo start --tunnel command exposes a local Metro bundler instance through a publicly reachable ngrok URL. The generated link allows any holder to load the running application without authentication, IP allowlisting, or token verification by default.
No built-in mechanism requires an explicit opt-in for access control when the tunnel is created. The CLI does not prompt for a password, enforce team membership, or integrate with Expo account permissions before publishing the URL. This behavior persists across current expo-cli and expo-dev-server versions.
29775 reputation · 22 Jan 2024, 13:26 UTC
Yes — as of current Expo CLI releases, expo start --tunnel creates a publicly reachable ngrok URL with no authentication challenge, no allowlist, and no prompt. Anyone who obtains the link can fetch your JavaScript bundle and hit Metro's endpoints. This is confirmed behavior, not a misconfiguration on your side. There is no built-in --tunnel-auth flag; access control has to come from a layer you add yourself.
Confirmed: the tunnel proxies your local Metro bundler through ngrok's free-tier edge, which serves requests without credentials. Metro itself has no auth middleware enabled by default. The bundle served over the tunnel contains whatever your app embeds — including any hardcoded API keys or non-secret-flagged environment variables.
Likely explanation: the tunnel exists for frictionless device testing (a teammate scans a QR code and the app loads). Adding an auth handshake would break that flow for the Expo Go client, which expects to fetch the manifest and bundle directly. So the CLI optimizes for the common case and leaves hardening to you.
Ctrl+C) when done — the URL dies with the process.npx expo start (default) or --lan keeps the bundler behind your network perimeter. Only use --tunnel when NAT or firewall rules genuinely require it.process.env.EXPO_PUBLIC_* is shipped to clients by design. Move real secrets behind a backend; never rely on tunnel obscurity.ngrok http 8081) with OAuth or basic-auth options on a paid plan gives you a gated tunnel, though this may break Expo Go's manifest fetch — verify with your actual client flow.Confirm the behavior on your own setup before assuming mitigations work:
npx expo start --tunnel
# From a phone on cellular (off your LAN), open the tunnel URL in a browser.
# If the bundle/manifest loads with no 401/403, the endpoint is open.You can also check the response headers with curl -I https://<your-tunnel-url> — an open tunnel returns 200 with no WWW-Authenticate challenge.
An opt-in auth mode (none/token/team) would be a reasonable CLI feature request, and short-lived signed URLs are technically feasible at the proxy layer. But there is no documented migration path for previously shared tunnel URLs — the only retroactive control is that tunnel URLs are ephemeral: once the session ends, the link is dead. If a URL leaked during an active session, restart the server to get a fresh one.
Note: ngrok's feature tiers and Expo CLI flags change over time — verify current options against the installed CLI's --help output before relying on any specific flag.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.