Skip to main content
VulnerabilityPublished

<p><strong><em>Description</em></strong>: Nodes without <code>--statedir</code> or <code>TS_STATE_DIR</code> failed to enforce signing checks in tailnets with Tailnet Lock enabled.</p> <h4>What happened?</h4> <p>In tailnets where <a href="https://tailscale.com/kb/1226/tailnet-lock">Tailnet Lock</a> is enabled, unsigned nodes running the <code>tailscaled</code> daemon (for example, on Linux) without specifying a <code>--statedir</code> or <code>--state</code> failed to enforce the required signing checks

Source GCVE Database

0

Fixed in 1.90.8 : update affected systems when convenient.

Data as of 13 Nov 2026, 18:29 UTC

Severity
Unrated

Rated by Threat Radar

Patch
Available – fixed in 1.90.8

Description

<p><strong><em>Description</em></strong>: Nodes without <code>--statedir</code> or <code>TS_STATE_DIR</code> failed to enforce signing checks in tailnets with Tailnet Lock enabled.</p> <h4>What happened?</h4> <p>In tailnets where <a href="https://tailscale.com/kb/1226/tailnet-lock">Tailnet Lock</a> is enabled, unsigned nodes running the <code>tailscaled</code> daemon (for example, on Linux) without specifying a <code>--statedir</code> or <code>--state</code> failed to enforce the required signing checks. This allowed them to communicate with other similarly misconfigured, unsigned nodes, or with malicious nodes that joined the tailnet. This behaviour bypassed the Tailnet Lock security policy for a specific subset of nodes.</p> <p>When Tailnet Lock is enabled, Tailscale nodes will only communicate if their node keys have been signed by a trusted signing node.</p> <p>The set of trusted signing nodes is tracked by the <a href="https://tailscale.com/kb/1226/tailnet-lock#tailnet-key-authority">tailnet key authority (TKA)</a>. This set is distributed to all nodes in the tailnet, and each node must store this state locally so that it can verify peer signatures.</p> <p>The TKA state is stored on disk in the state directory. Prior to 1.90.8, this was the only storage option.</p> <ul> <li>If you use the macOS, Windows, iOS, Android, and tvOS clients, the state directory is set automatically.</li> <li>If you run the <code>tailscaled</code> daemon, the state directory is set by the <a href="https://tailscale.com/kb/1278/tailscaled#flags-to-tailscaled"><code>--statedir</code></a> or <code>--state</code> flags.</li> <li>If you use the default systemd unit files distributed with the official Tailscale <code>deb</code>, <code>rpm</code>, and <code>tar.gz</code> packages, the <code>--state</code> flag is set automatically.</li> <li>If you use Tailscale in Docker or Kubernetes, the state directory is set by the <a href="https://tailscale.com/kb/1282/docker#ts_state_dir"><code>TS_STATE_DIR</code> environment variable</a>.</li> </ul> <p>If <code>tailscaled</code> was started without a state directory (<code>--statedir</code>, <code>--state</code>, and/or <code>TS_STATE_DIR</code> were omitted), it would be unable to store the set of trusted signing nodes. Rather than failing and reporting an error, such a node erroneously skipped checking whether peer signatures were signed, which is a failure to enforce Tailnet Lock.</p> <h4>What was the impact?</h4> <p><strong>There is no indication of this issue being exploited in the wild.</strong></p> <p>The bug allowed communication between two or more unsigned nodes, each running without a state directory, even though Tailnet Lock was enabled.</p> <p>While the bug is present across many versions, the risk of exploitation is low. It was not possible for an unsigned node without a <code>--statedir</code> to connect to a node that did have a state directory, as the latter would correctly enforce the policy and reject the connection from the unsigned peer.</p> <h4>Who was affected?</h4> <p>The vulnerability only manifests when all three of the following conditions are met:</p> <ol> <li>Tailnet Lock is enabled in the tailnet,</li> <li>At least two nodes were running the <code>tailscaled</code> daemon without the <code>--statedir</code>/<code>--state</code> flags, or without the <code>TS_STATE_DIR</code> environment variable, and</li> <li>At least one of the node keys was not signed.</li> </ol> <p>This bug was present in all Tailscale clients from the introduction of Tailnet Lock, and is fixed in version 1.90.8.</p> <p>You can tell if a node is affected by this issue by running <code>tailscale lock status</code>. If the output says <code>Tailnet Lock is NOT enabled</code> but Tailnet Lock is enabled in your Tailnet, the node is not enforcing signing checks correctly.</p> <p>Alternatively, you can look for the following text in your <a href="https://tailscale.com/kb/1011/log-mesh-traffic">client logs</a>:</p> <pre><code>network-lock unavailable; no state directory </code></pre> <p>(The pre-release name for Tailnet Lock was "network lock", which still persists in parts of the codebase.)</p> <h4>What do I need to do?</h4> <p>If you don't use Tailnet Lock, no action is required.</p> <p>If you do use Tailnet Lock:</p> <ol> <li> <p><strong>Review the configuration of any nodes that run the <code>tailscaled</code> daemon.</strong> Specifically, check the startup parameters for the <code>tailscaled</code> service. Any nodes running <code>tailscaled</code> without a state directory are potentially vulnerable until upgraded.</p> </li> <li> <p><strong>Upgrade all nodes running the <code>tailscaled</code> daemon to 1.90.8 or later.</strong> Alternatively, set a state directory by:</p> <ul> <li>Adding the <code>--statedir</code> flag if you run the <code>tailscaled</code> daemon, or</li> <li>Adding the <code>TS_STATE_DIR</code> environment variable if you run Tailscale in Docker or Kubernetes.</li> </ul>

Community reviews

Loading reviews…