qurl. link
Localhost safety

Is it safe to expose localhost to the internet?

Not with a public URL. Dev servers aren’t built for hostile traffic, and a public tunnel URL puts yours on the internet: anyone with the address can reach it. Some tunnel hostnames also appear in public Certificate Transparency logs. Keep the server bound to localhost and share it with access that ends on its own.

What a public URL exposes

Four things to know first.

Anyone with the address

A public tunnel URL works for whoever has it, for as long as the tunnel runs. If the link gets forwarded, the next person is in too.

Names in public logs

Certificate Transparency logs are public. A peer-reviewed study measured the first requests arriving 5.9 minutes, on average, after a certificate was registered. Tailscale’s docs warn that machine names are published in those logs when HTTPS is on, which Funnel requires.

A dev server on the internet

CISA’s Known Exploited Vulnerabilities catalog lists developer and AI tools such as Langflow, LiteLLM, n8n, Ray and MLflow. Its Vite entry applies only to dev servers exposed to the network, and a public tunnel URL exposes yours.

Tunnels attackers use

Security vendors, governments and tunnel providers have documented criminals using ngrok and Cloudflare tunnels for malware delivery, phishing and ransomware.

Sources and data: The Localhost Exposure Report 2026.

Tool by tool

Who can reach your app.

qurl.link

qURL CLI

Who can reach it
No one until a link is opened. Then the network it was opened from, for that visit.
The address
A qurl.site name. The app has no public route.

ngrok

ngrok agent

Who can reach it
Anyone with the URL, unless you add sign-in rules.
The address
A dev domain from ngrok that stays the same.

Cloudflare quick tunnel

cloudflared

Who can reach it
Anyone with the URL, unless you set --allowed-mail.
The address
A trycloudflare.com name that changes each run.

Tailscale Funnel

Tailscale client

Who can reach it
Anyone on the internet.
The address
A ts.net machine name, published in Certificate Transparency logs.

Every tool side by side, with sources: every way to share localhost.

If you share a local app

Share it the careful way.

  • Keep dev servers and model servers bound to localhost. Avoid --host and 0.0.0.0.
  • Prefer access you can take back: an invitation you can revoke, or an app you take offline.
  • Keep your app’s own login for anything sensitive, whatever carries the traffic.
  • Know who shares the network: opening a qURL link admits the network it was opened from for that visit, so other devices on the same public IP, such as an office Wi-Fi, can reach the app until the visit ends.
With qURL

Share it with no public URL.

Share it with qURL

  1. Install the qurl CLI.

    On a Mac, use Homebrew. On Linux and Windows, download the .deb, .rpm or archive from the CLI releases and put qurl on your PATH. No account to make first.

    Install (macOS)
    $ brew install layervai/tap/qurl
  2. Publish the app that’s running.

    Use your app’s port and choose the access policy: review lets people ask and you approve each one; invite_only admits only the people you invite. The app stays on your computer. Nothing is uploaded or deployed, and the first publish creates a free identity for this computer.

    Publish
    $ qurl publish http://127.0.0.1:3000 --access review
  3. Send the address, then approve who asks.

    Send the address that qurl publish returned. Each person who opens it asks for access, and nobody gets in before you approve them: list the requests, then approve the one you chose by its decision ID. Rather invite people by email? Publish with --access invite_only instead and let your AI send the invitations.

    Approve a request
    $ qurl access list_grants <id> -o json
    $ qurl access approve <id> <decision-id> --version <current-version> -o json

Done sharing? qurl stop <id> takes the app offline, and qurl delete <id> --yes retires it: its links stop working and open visits end.

When a public URL is the point

When to use something else.

  • Stripe, GitHub or another service has to call your webhook?Use a public tunnel
  • You need a public URL anyway?Add sign-in rules
  • Everyone who needs it is on your tailnet?Use Tailscale Serve

qURL is not for webhooks, public APIs or raw TCP. Use a public tunnel for those.

Made a thing?

Start with qurl.link.
Show someone today.

Free to try. No account needed. Current limits