---
title: "One Hacked Laptop, Root on Every Server You Can Reach"
slug: "tailscale-tailworm-root-escalation"
language: "en"
date: "2026-10-28T04:34:50.862Z"
updated: "2026-10-28T04:34:50.000Z"
description: "Tailworm (TS-2026-014) let any compromised tailnet device get root on reachable servers via SSH socket forwarding. The fix is 1.104.4; the policy is the other half."
canonical: "https://fix.slopit.io/tailscale-tailworm-root-escalation/"
tags: ["security", "networking", "ssh", "infrastructure"]
---

A mesh VPN is supposed to make the network boundary disappear so that identity can replace it. Tailworm is a reminder that when you remove the boundary, the weakest endpoint becomes the perimeter.

The bug, tracked as TS-2026-014 and fixed in Tailscale 1.104.4, is a privilege escalation in Tailscale SSH. If one device on your tailnet is compromised — a laptop, a CI runner — it can get root on every server its SSH policy lets it reach. No password, no key. The attacker opens an ordinary SSH session, asks for socket forwarding, and the root `tailscaled` process does the rest.

Cyberdione Labs published the findings on 25 October, before a fix existed. Tailscale tagged 1.104.4 on 27 October alongside advisories TS-2026-014 through TS-2026-017. In the researcher's lab, on unmodified 1.104.2 and headscale 0.29.5, it chained machine to machine in under a second per hop with no user interaction. Neither Tailscale nor the report mentions exploitation in the wild, and that distinction matters.

## What actually went wrong

The design is reasonable on its face: Tailscale SSH replaces key management with identity-based policy, so the daemon checks whether this user on this device may reach that server, then handles the connection.

The forwarding path is where it broke. Before the fix, Tailscale SSH checked forwarded Unix socket paths against an allowlist by name, and then performed the dial, bind, or unlink as root. That gave three ways in:

- `ssh -L` to a Unix socket dialed it as root, so a normal session could talk to root-only sockets — the Docker socket, or the `tailscaled` local API.
- `ssh -R` could unlink a root-owned socket and put the attacker's listener in its place.
- A race between the path check and the use of that path, a classic TOCTOU — check, then act, with the state changing in between.

All three are fixed by the release. But the shape of the bug is instructive: the authorization decision was about the user and device, while the privileged action was performed by the server's own daemon, as root, on behalf of that user. The escalation lived in the gap between "this session is authorized" and "this root process will act for it."

## The policy is half the vulnerability

The advisory's remediation has two halves, and the second is the one people will skip.

The first is the upgrade: version 1.104.4 on every node running Tailscale SSH or `tailscale serve`. If your mirror or image doesn't carry it yet, Tailscale's interim fix is `TS_SSH_DISABLE_FORWARDING=1`, which keeps Tailscale SSH working and closes the forwarding paths. That's a good stopgap because it removes the feature that caused the escalation rather than disabling remote access entirely.

The second is the policy, which the upgrade doesn't touch. "Any member to any tagged server" is a common default and, in this bug's terms, a blast radius: one compromised laptop inherits reach to everything. The report says per-pair rules alone stopped the spread in the lab. It also recommends stop granting `root` or passwordless-sudo accounts as SSH targets, which is the multiplier that turns a compromised endpoint into full control.

On Tailscale's hosted control plane you can also deny forwarding per SSH rule. On headscale 0.29.5 you can't, which is why the report treats every SSH grant there as root on the target. If you run headscale, that's the sentence to read twice.

## The uncomfortable inversion

Normally, access control is about what the client is allowed to ask for. Here, the client asks for something ordinary — port forwarding, a feature SSH has had forever — and the server's root process does something privileged on its behalf.

That's the structural risk of "SSH without keys": you're not removing authentication, you're moving it. The identity check happens in the daemon, but the daemon runs as root, so any feature that lets the session reach a privileged socket is effectively a privilege boundary, and it has to be designed as one. Forwarding is not a convenience here; it's an execution surface.

Mesh networks concentrate this risk. In a traditional network, a compromised laptop sits behind a firewall and has to pivot. In a tailnet, the laptop is already inside, and the only thing between it and the servers is policy. That's the point of the design, and it's also why a forwarding bug in the daemon is worse than the same bug in a conventional SSH server: the attacker doesn't need to reach the machine, because the machine is already a member.

## What to do this week

Upgrade every node. If you can't, disable forwarding. Then read your SSH rules and ask a blunt question: if this laptop were compromised right now, what could it reach? If the answer is "everything tagged production," the bug isn't the only problem.

And check whether any rule targets root or a passwordless-sudo account. That's not a policy, it's a shortcut with a security review pending.

## The takeaway

Tailworm is a good bug: a real escalation, a clear fix, a lab demonstration, no known exploitation. The reason to pay attention is the pattern it exposes — identity-based access is only as strong as the local privilege boundary it delegates to, and convenience features like forwarding are where that boundary gets crossed.

The perimeter didn't disappear. It moved to the endpoint, and the endpoint was always the weakest part.

*Source: [Tailworm turns one hacked laptop into root on your Tailscale SSH servers — HOL](https://hol.org/blog/tailscale-tailworm-ssh-root-escalation-ts-2026-014-upgrade-1-104-4).*
