DEV Community

Tailworm: eleven unfixed flaws in a mesh VPN, and the SSH path that carries root

A mesh VPN is usually deployed so that nobody has to publish an administrative interface. Tailscale builds a tailnet out of WireGuard peer-to-peer links, and headscale reimplements the control server for teams that want to run it themselves.

That design removes public load balancers and open ports, which is why so many engineering teams treat the tailnet as an internal network with a login attached. A security audit published this week argues that the login is doing more work than the operators think.

Cyberdione Labs reported eleven vulnerabilities in Tailscale 1.104.2 and in the self-hosted headscale v0.29.5 control server. The researchers grouped them under the name Tailworm and released the details publicly after reporting them to the vendor.

Erica Windisch, the founder of Cyberdione Labs, said every finding was verified by reproduction in a lab on unmodified, released software. Tailscale has acknowledged the reports, described them as serious, and said it was working on patches with a target of the end of Tuesday, October 27.

The SSH forwarding path is the one to read first

Tailscale SSH is served by tailscaled, the same daemon that runs as root on every node. When the embedded SSH server handles remote or local port forwarding, it performs path checks and file operations with root privileges.

The report describes races in that sequence and a missing privilege drop, which together let an ordinary forwarded session replace, dial or delete privileged resources on the target host.

The practical outcomes listed in the research are:

  • root code execution on the target server
  • capture of enrollment keys
  • arbitrary deletion of files owned by root

The precondition is smaller than it sounds. An attacker needs one approved device on the tailnet and one SSH policy rule that grants forwarding. On headscale, the report says forwarding is granted automatically; on the SaaS product the grant follows the individual rule, so a narrow policy is a narrower exposure.

Because the flaw lives in the forwarding machinery rather than in the authentication step, the session that triggers it has already passed whatever identity check the policy applies. That ordering matters for incident review.

A successful attack against this path looks like an authorised session from a known device, not like a brute-force attempt or a stolen password. Logs will show a legitimate tailnet peer opening a forwarded socket.

App connectors, relays and the control server

A second cluster of findings concerns app connectors, the experimental component named conn25 in the report. A connector translates traffic toward a destination chosen by the caller, and the research says the true destination is never validated and network ACLs are not consulted.

A device holding the connector capability can therefore reach cloud metadata endpoints and internal LAN segments that the tailnet policy was meant to segment off. In Kubernetes, the same behaviour reaches every cluster service.

The headscale control server has a separate problem. The report describes unauthenticated resource exhaustion through memory growth and cache eviction, reachable by anyone who can open a connection to the server. The result is a crash loop that blocks new device onboarding for the whole organisation.

No account is required, which puts the control plane in the same category as any other internet-facing service rather than in the protected category that self-hosted infrastructure usually assumes.

Two further issues round out the set. The DERP client, the relay connection present in every agent, reads a hostile relay response without a bound, so a client that can be pointed at an attacker-controlled relay can be made to exhaust memory. Tailscale serve has a TCP forward to a Unix socket that lacks a guard present on the HTTP path, plus a race in per-mount authorisation, which the report says can yield remote access to the node's administrative API and let a minority of requests bypass application authorisation.

What the vendor says, and what it does not settle

Tailscale confirmed the reports and said patches were being prepared by the end of the day, then by the end of Tuesday. Its statement frames the SSH findings around privilege escalation: someone already authorised to connect over Tailscale SSH may, in some circumstances, perform actions beyond the permissions of the configured local user.

The vendor adds that exploitation depends on the permissions granted to the connecting user or device, the system configuration and other conditions, and that it is still verifying the full scope.

The company does not recommend that customers disable Tailscale SSH. Instead it points to three controls:

  1. review SSH access policies and limit them to the users and devices that need access
  2. set TS_SSH_DISABLE_FORWARDING=1 in the tailscaled service environment and restart the service
  3. consider temporarily tightening access to sensitive systems while the investigation continues

The second control is the interesting one, because it removes the forwarding machinery from the attack path without disabling SSH itself.

A remediation order for tailnet owners

The first decision is whether forwarding is used at all. A team that relies on ssh -L to reach databases through a jump host cannot simply switch the setting off, and a team that never uses it should. Answering that question requires reading the SSH policy rules rather than the general access policy, because forwarding is granted per rule on the SaaS product.

The second decision is about connector exposure. Any device granted the connector capability can currently name a destination that the ACL does not cover, so the capability deserves the same scrutiny as a route table entry. Where connectors are experimental, the practical option is to withdraw the capability until the vendor ships a fix and the behaviour is verified.

The third is the control server. A headscale deployment reachable from the internet is exposed to the unauthenticated exhaustion issue, and the mitigation is network placement: restrict who can reach the control port and monitor for restart loops that block enrollment. Self-hosted infrastructure behind a VPN is easier to restrict than a distributed SaaS client fleet.

None of these steps depends on knowing the exploit. They depend on knowing which capabilities each node holds, which is the inventory problem that mesh networks tend to hide, since the point of the mesh is that every node can reach every other node once policy allows it.

References

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.