Your Localhost Is Not Private: Securing Developer Environments Against Localhost SSRF and DNS Rebinding
Exposed local ports let malicious webhooks pivot into your internal network. Learn to stop localhost SSRF and DNS rebinding attacks with InstaTunnel.

Quick answer
Securing Dev Tunnels: Stop Localhost SSRF & DNS Rebinding: webhook testing answer
For local webhook testing, run your app locally, expose it with a public HTTPS tunnel, and paste the stable callback URL into the provider dashboard.
How do I test webhooks on localhost?
Start your local server, open a public HTTPS tunnel to that port, configure the provider webhook URL, and inspect events in your local logs.
Why does a stable webhook URL matter?
Stable URLs prevent provider dashboards from needing manual callback updates every time you restart a tunnel.
Most developers treat localhost as a trust boundary. Anything bound to 127.0.0.1 is assumed to be reachable only by you. That assumption has failed repeatedly, in browsers, AI tooling, dev servers and container runtimes.
This article covers two related attack classes, how they hit developer machines, the browser changes of the last two years, and what to do about them. It also covers where a tunneling tool such as InstaTunnel helps and where it does not.
Two attack classes, one false assumption
Localhost SSRF is server-side request forgery aimed at loopback. An application fetches a URL the attacker controls (a webhook target, an image URL, a link preview) and the attacker points it at 127.0.0.1, 0.0.0.0 or an internal address. The server then makes the request from inside the trust boundary, to services that never expected outside callers.
DNS rebinding works from the browser. A victim visits an attacker’s page. The attacker’s domain first resolves to the attacker’s server, then to 127.0.0.1, so the browser keeps treating requests as same-origin while they reach the victim’s local service. Vite’s advisory describes this chain: the attacker changes the DNS answer to point at 127.0.0.1 or another private address, and an HTTP server that does not validate the Host header cannot tell the difference.
Both rely on the same bad assumption: reaching a local port means the caller is trusted.
The 0.0.0.0 Day vulnerability
In August 2024, Oligo Security disclosed “0.0.0.0 Day”, a logic flaw in how major browsers (Chromium, Firefox, Safari) handled requests to 0.0.0.0. Oligo had reported it to the browser vendors in April 2024.
- The mechanism. Private Network Access (PNA) was meant to stop public websites from reaching private addresses. But
0.0.0.0was not on the list of private or local ranges, so requests to it slipped past. - Who was affected. The issue affected macOS and Linux but not Windows. Oligo’s researcher said that public sites could reach any open port on the host, but without being able to read the response, so the exposure is mostly about blind, state-changing requests.
- Age. It is not new in the sense of “recent”. Oligo’s disclosure echoed a bug reported to Mozilla in 2006.
- The fixes. Chrome began blocking
0.0.0.0in Chromium 128, with a gradual rollout meant to finish by Chrome 133. Apple changed WebKit to block it. Mozilla changed the Fetch standard to block it but, at the time, had no shipped Firefox fix.
Rollout was uneven. When Oligo published its 2025 write-up on the MCP Inspector flaw (below), it still listed the 0.0.0.0 behavior as unresolved in Chromium and Firefox. Do not assume every browser on your team is protected.
Real exploitation: MCP Inspector
CVE-2025-49596 hit the MCP Inspector, a developer tool for testing MCP servers. It was rated Critical (CVSS 9.4). Versions before 0.14.1 had no authentication between the Inspector client and its local proxy. By chaining a CSRF-style request with 0.0.0.0 Day, a malicious website could send commands to that proxy and run code on the developer’s machine. Version 0.14.1, released June 13, 2025, added a session token by default and host checking.
Why AI tooling made this worse
Local AI tools tend to run unauthenticated HTTP or WebSocket servers on loopback, because “it’s only local”. Three recent cases show the pattern.
MCP SDKs (December 2025). CVE-2025-66416 (Python SDK, fixed in 1.23.0) and CVE-2025-66414 (TypeScript SDK, fixed in 1.24.0) were disclosed because the SDKs did not enable DNS rebinding protection by default for HTTP-based servers. An unauthenticated MCP server on localhost could be reached from a malicious website, which could then invoke its tools. Servers using stdio transport are not affected.
ClawJacked (February 2026). Oasis Security showed that any website could hijack a local OpenClaw agent. Browsers do not block WebSocket connections to localhost on cross-origin grounds, so page JavaScript could open a socket to the gateway and guess its password. The gateway exempted localhost from rate limiting and auto-approved device pairing from localhost, so a successful guess gave persistent access. A fix shipped within about a day.
NVIDIA NemoClaw and Ollama (August 2026). Oasis Security reported that a malicious webpage could take over the Ollama instance behind NemoClaw on one setup path. Ollama had fixed its own DNS rebinding bug (CVE-2024-28224) in v0.1.29 by validating the Host header. The report says that validation is skipped when Ollama is bound to a non-loopback address, and that the Windows-host path sets OLLAMA_HOST=0.0.0.0:11434. The attacker could then rewrite the model’s chat template to plant persistent instructions. The research has no CVE, and no exploitation had been reported as of August 25, 2026. According to the researcher, a fix covered macOS and Linux in NemoClaw v0.0.35 but not the Windows and WSL path. Check current status before relying on this.
The lesson is that binding to 0.0.0.0 can quietly switch off protections that only apply to loopback.
Dev servers and container runtimes
Vite (CVE-2025-24010). Before the fix, any website could send requests to the dev server and read the responses, because of permissive default CORS settings and missing Origin validation on WebSocket connections. This applied even to servers only running on the local machine. It is fixed in Vite 6.0.9, 5.4.12 and 4.5.6. The new server.allowedHosts option allows localhost, *.localhost and IP addresses by default. Vite’s docs warn that setting it to true lets any website reach your dev server through DNS rebinding, and recommend an explicit list.
Docker Desktop (CVE-2025-9074). Docker’s Engine API was reachable at 192.168.65.7:2375 from any container, without authentication. The flaw was rated 9.3 (CVSS) and fixed in Docker Desktop 4.44.3. It affected Windows and macOS but not Linux, because the Linux version uses a local socket rather than a TCP port. SOCRadar classifies it as SSRF: a request forged from inside a container reached a control plane that assumed all callers were trusted.
What browsers now do
Chrome’s earlier plan, Private Network Access with CORS preflights, went on hold because of compatibility problems. Before pausing, Chrome added 0.0.0.0/8 to PNA’s local ranges.
The replacement is Local Network Access (LNA):
- Chrome 142 (October 28, 2025) gates requests from public sites to local or loopback addresses behind a permission prompt. Other Chromium browsers followed.
- Chrome 145 split the permission into
local-networkandloopback-network, according to a Chrome team tracking issue. The same issue says Chrome 147 extends the restrictions to WebSocket and WebTransport, and that the temporary enterprise opt-out policy is slated for removal in Chrome 156. - Firefox has a similar prompt. Mozilla’s support page says it applied from version 149 for users on Strict Enhanced Tracking Protection, with a gradual rollout to all users from version 151.
These are real improvements, but they are defense in depth. They prompt users and gate cross-site requests; they do not make an unauthenticated local service safe. DNS rebinding and malicious software already on the machine are separate problems. The standard fix for rebinding, as stated in coverage of the NemoClaw research, is verifying Host and Origin headers on the server. Treat browser controls as a second layer.
Hardening the app: a checklist
- Authenticate every local service, even on loopback. Use a random token, not “it’s only localhost”. CVE-2025-49596 and ClawJacked both came down to missing or weak authentication.
- Allowlist the
Hostheader and reject anything else. This is the core defense against DNS rebinding. Never use a wildcard or “allow all” setting (Vite’sallowedHosts: true). - Validate
Originon state-changing requests and WebSocket upgrades. CORS does not govern WebSocket connections, so it cannot protect them. - Apply rate limits to localhost too, and do not auto-approve pairing or registration from loopback.
- Bind to
127.0.0.1, not0.0.0.0, unless you need LAN access. If a container or WSL setup forces a wider bind, confirm which host checks are still active. - Prefer stdio or local sockets over TCP for local-only communication. MCP’s stdio transport is not exposed to the browser attack, and Docker’s Linux architecture avoided CVE-2025-9074 for the same reason.
- Patch. The versions above are the minimum: Vite 6.0.9 / 5.4.12 / 4.5.6, MCP Inspector 0.14.1, MCP Python SDK 1.23.0, MCP TypeScript SDK 1.24.0, Ollama 0.1.29, Docker Desktop 4.44.3.
Hardening the server-side fetcher (localhost SSRF)
If your backend fetches user-supplied URLs:
- Prefer an allowlist. The OWASP SSRF Prevention Cheat Sheet says deny-lists are bypass-prone. Where possible, match the host against known destinations and build the request yourself.
- Block all local representations, not just
127.0.0.1. OWASP lists127.0.0.0/8,0.0.0.0/8and::1/128for localhost. Public bypass lists show many variants:127.1,0,[::], decimal2130706433, hex0x7f000001, and IPv4-mapped IPv6 forms. - Resolve, then validate, then pin. Look up both A and AAAA records, check every address against your blocked ranges, and connect to the validated IP. Otherwise a hostname can pass validation and re-resolve to a private address for the real request.
- Re-validate redirects. A redirect target is a second request that needs the same checks.
- Block link-local and private ranges, including the cloud metadata address
169.254.169.254.
Where a tunnel fits
A tunnel reverses your exposure: instead of a localhost service that only your browser can reach, you have a service that anyone with the URL can reach. That is useful for webhooks, OAuth callbacks, demos and MCP testing, but it means the checklist above becomes mandatory rather than optional.
A tunnel also does not fix the issues above. It cannot add Host validation to your dev server or authentication to your MCP endpoint. What it can do is put access control in front of the local service, so you do not depend on the service’s own defaults. Based on InstaTunnel’s documentation:
- Edge authentication.
--passwordand--auth user:passprotect a tunnel. These need a Pro or Business plan. As of CLI 1.1.24, password and Basic Auth settings are enforced before requests are forwarded to your machine.
instatunnel 3000 --subdomain acme-qa --auth qa:review-secret
- MCP tunnels with a bearer token.
--mcprequires Pro or Business. The docs show generating a token withnode -e "console.log(require('crypto').randomBytes(32).toString('hex'))"and using it as anAuthorization: Bearerheader. Your MCP server must enforce the token itself; the client does not require it by default.
instatunnel 8787 --mcp --transport v2 --subdomain mymcp
- Traffic policies. InstaTunnel’s traffic policy docs describe IP allow and deny rules by CIDR range, header rules, per-IP/API-key/user rate limits (returning 403 or 429 when blocked), and audit records for blocked requests. These are managed by admins through
/admin/policies. - Visibility and cleanup.
--logs(Pro/Business) polls request logs, and--kill <subdomain>stops a tunnel. For QA links, the docs recommend rotating credentials and stopping the tunnel after review.
One practical wrinkle: if your tunnel forwards its public hostname in the Host header, a Host allowlist like Vite’s allowedHosts will reject it until you add that exact hostname. Add the specific hostname you control, not a wildcard and not true. Check what your tunnel actually sends before relying on this.
Summary
- 0.0.0.0 Day is a 2024 browser flaw, mitigated unevenly. It was exploited in practice against developer tools like MCP Inspector.
- DNS rebinding keeps resurfacing in dev tools, from Ollama in 2024 to MCP SDKs in 2025 to NemoClaw in 2026. The fix is always server-side: authenticate, and validate
HostandOrigin. - Browser permission prompts (Chrome 142+, Firefox 149+) reduce exposure but do not replace those checks.
- Server-side fetchers need allowlists, full address-family resolution and pinned connections.
- Tunnels should add authentication and access control in front of your service, never be the only barrier.
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.