TS-2026-009
Description: Insecure command line argument handling in Tailscale SSH permitted root user access in violation of ACLs.
What happened?
Tailscale SSH previously accepted usernames that contained a leading - character. On Linux platforms these usernames were passed as arguments to getent(1) to retrieve the corresponding passwd entry, where they were interpreted as flags permitting attacker-controlled behavior. Specifically, if a user connected with the username -i this would have been interpreted as --no-idn and getent would have printed the entire passwd file contents starting with the root user, causing Tailscale to open an interactive root session.
Tailscale SSH now rejects usernames with leading dashes.
This vulnerability is fixed in Tailscale version 1.98.9 or newer.
What was the impact?
A user with SSH access to a Linux node would have been able to obtain a root session by connecting with the username -i, in violation of ACL policy.
Who was affected?
Users of Tailscale SSH on Linux hosts that rely on autogroup:nonroot user restrictions in Tailscale ACLs.
What do I need to do?
If you use Tailscale SSH, upgrade to Tailscale version 1.98.9 or newer.
Credits
We would like to thank Anthropic and Ada Logics for reporting this issue.
TS-2026-008
Description: A single malformed HTTP request to a node running Tailscale Serve or Funnel could pin a CPU core indefinitely, causing denial of service.
What happened?
Tailscale Serve and Tailscale Funnel proxy incoming HTTP requests to local backends by matching the request path against the configured mount points. When resolving the handler for a request, Tailscale walked the request path upward one directory at a time, expecting the walk to eventually terminate at the root path /.
For requests whose path did not begin with /, this walk never reached / and never matched a mount point, causing the loop to spin forever. As the server enforced no request timeout, nothing interrupted the spin, and the goroutine held one core at 100% for the life of the process.
Tailscale now terminates the path walk for non-absolute paths, returning no handler and closing the request.
This vulnerability is fixed in Tailscale version 1.98.9 or newer.
What was the impact?
An attacker could send a crafted HTTP request to permanently consume one CPU core on the target node.
For Tailscale Serve, the request could originate from any peer on the tailnet with access to the node. For Tailscale Funnel, the request could originate from any unauthenticated host on the internet.
Who was affected?
Nodes running Tailscale Serve or Tailscale Funnel on versions prior to 1.98.9.
What do I need to do?
If you run Tailscale Serve or Tailscale Funnel, upgrade to Tailscale version 1.98.9 or newer.
Credits
We would like to thank Anthropic and Ada Logics for reporting this issue.
TS-2026-007
Description: Insufficient inbound packet filtering in Services permitted access to loopback-bound listeners.
What happened?
Tailscale Services are virtual tailnet destinations that can be hosted from one or more nodes on your tailnet. They allow you to manage networked resources such as databases separately from the nodes that back them.
In Tailscale versions prior to 1.98.9, nodes advertising services could accept inbound traffic to service IPs on ports that they did not advertise. In these scenarios Tailscale would forward these packets to any process on the host loopback interface listening on the same port, allowing them to be accessed remotely.
Tailscale now filters and rejects these packets with the appropriate TCP RST response when no corresponding handler exists for the service port.
This vulnerability is fixed in Tailscale version 1.98.9 or newer.
What was the impact?
A user with ACL grants to a Tailscale Service could address it on non-advertised ports and reach processes listening on loopback on the node hosting the service.
Who was affected?
Users of Tailscale Services that rely on loopback-only network access restrictions on the nodes they use to host services.
What do I need to do?
If you host Tailscale Services on nodes alongside processes bound to loopback, upgrade to Tailscale version 1.98.9 or newer.
TS-2026-006
Description: Tailscale SSH allowed users to be addressed by numeric UID, bypassing root user restrictions in ACLs.
What happened?
Tailscale SSH previously allowed users to be addressed by their username or UID value, however the root user restrictions in ACL enforcement only considered the former. A user with non-root SSH access who addressed 0@host would have been able to access root in violation of ACLs.
Tailscale now disallows the use of UIDs or numeric-only usernames via SSH to avoid this ambiguity.
This vulnerability is fixed in Tailscale version 1.98.9 or newer.
What was the impact?
A user with SSH access to a node would have been able to SSH as root using the username 0 in violation of ACL policy.
Who was affected?
Users of Tailscale SSH on Linux/Unix hosts that rely on autogroup:nonroot user restrictions in Tailscale ACLs.
What do I need to do?
If you use Tailscale SSH, upgrade to Tailscale version 1.98.9 or newer.
Credits
We would like to thank Tim Hoffman (GM) for reporting this issue.
TS-2026-005
Description: Tailscale Serve Unix socket proxy targets were not restricted to root, allowing a non-root operator to proxy privileged sockets.
What happened?
Tailscale Serve can proxy incoming connections to local backends, including Unix domain sockets configured as proxy targets (for example, proxy: unix:/var/run/docker.sock). A non-root local user configured as the Tailscale operator can write Serve configuration through the LocalAPI.
Tailscale restricts the ability to specify filesystem paths as Serve targets to the root user to prevent privilege escalations, however this check did not cover Unix socket proxy targets. A non-root operator could therefore have the tailscaled process running as root proxy to a privileged Unix socket, bypassing the filesystem permissions that would otherwise deny them access.
Tailscale now restricts Unix socket proxy targets to the root user, matching the requirement already applied to filesystem handlers.
This vulnerability is fixed in Tailscale version 1.98.9 or newer.
What was the impact?
A non-root user configured as the Tailscale operator could cause the tailscaled process running as root to connect to privileged Unix sockets they could not otherwise access.
Who was affected?
Linux/Unix hosts running Tailscale Serve where a non-root local user was configured as the Tailscale operator and privileged Unix sockets (such as Docker, containerd, or CRI sockets) were present.
What do I need to do?
If you use Tailscale Serve, upgrade to Tailscale version 1.98.9 or newer.
Credits
We would like to thank Tim Sageser (dtrsecurity) for reporting this issue.
TS-2026-004
Description: Tailscale SSH Unix socket forwarding did not respect symlink permissions, allowing privileged socket access.
What happened?
Tailscale SSH includes the ability to forward both TCP and Unix sockets between the client and host. A bug in the filesystem permission checks within Tailscale SSH's Unix socket forwarding permitted an unprivileged user to bind and access a privileged socket on the remote host.
Previously, when Tailscale SSH evaluated filesystem permissions for requested sockets, it only performed lexical matching of the requested path against its allowlists and denylists. An attacker who created a symlink at a path they owned (e.g., /home/$USER/my.sock) that pointed to a protected resource (e.g., /var/run/docker.sock) would have been able to bind and access the latter path in an SSH connection. This is possible because Tailscale runs as root and so has access to the privileged destination.
In addition to lexical matching, Tailscale SSH now checks the requested and configured paths for symlinks and evaluates them to ensure that their destinations are also authorized. Symlinks with destinations outside of the configured allowlist will be denied.
This vulnerability is fixed in Tailscale version 1.98.9 or newer.
What was the impact?
An unprivileged user would have been able to access privileged Unix sockets on the remote host.
Who was affected?
Users of Tailscale SSH on shared Linux/Unix hosts that rely on filesystem permissions to restrict access to Unix sockets.
What do I need to do?
If you use Tailscale SSH, upgrade to Tailscale version 1.98.9 or newer.
Credits
We would like to thank Tim Sageser (dtrsecurity) for reporting this issue.
TS-2026-003
Description: OAuth access tokens recorded in tailnet audit logs.
What happened?
The Tailscale coordination server emits an audit log recording all changes to a tailnet's configuration including the creation and management of access credentials.
A bug in the Tailscale coordination server caused it to record the complete OAuth client access tokens within the audit log entries that describe their creation. This made the OAuth access tokens accessible to other tailnet actors who had access to the logs.
What was the impact?
A tailnet admin with access to audit logs would have been able to retrieve OAuth access tokens from the logs and use them to make authorized requests to the Tailscale API within the token's one hour validity window.
Who was affected?
All tailnets that used OAuth Clients to create access tokens from March 1st, 2026 to May 29th, 2026 are impacted.
What do I need to do?
There is no action necessary on the part of customers. New access tokens are now recorded in a redacted form in the audit log. Access tokens are created with a maximum valid lifetime of one hour so all historical tokens have already expired.
Credits
We would like to thank Conor Power (Snapchat) for reporting this issue.
TS-2026-002
Description: ACL capability bypass in the Tailscale client's web interface
What happened?
The Tailscale client runs a local web interface to manage its settings. This web interface can optionally be opened to other tailnet peers, for example to manage a tagged node on a headless host without SSH access. By default the interface is read-only, but tailnet admins can grant permissions to change certain settings using ACL grants.
The /api/routes endpoint on the web interface allows changing the active
exit node and advertised subnet routes.
These settings are gated behind exitNodes and subnets grants respectively.
There was a bug in the handler that reset both settings to their empty state if the request body was empty, even if the caller doesn't have either grant to allow that.
This vulnerability is fixed in Tailscale version 1.98.0 and newer.
What was the impact?
A malicious tailnet node could disable the exit node and clear advertised
subnet routes on other tailnet nodes that run the web interface. The malicious
user would need to perform a login check and be granted access to port 5252
on the target node via tailnet ACLs.
Who was affected?
Linux, macOS, and Windows nodes running Tailscale between versions 1.56.0 and 1.98.0 and with the web interface explicitly enabled.
What do I need to do?
If you are using the web interface to manage remote nodes, update those nodes to version 1.98.0 or newer.
Credits
We would like to thank N0zoM1z0 for reporting this issue.
TS-2026-001
Description: Arbitrary command execution with elevated privileges in tssentineld
What happened?
tssentineld is a launchd service that is installed in managed environments
when the AlwaysOn.Enabled MDM policy is present on macOS. Its sole
responsibility is to ensure that Tailscale.app is relaunched if terminated.
As a launchd service, it runs as root.
The implementation used an NSTask and /bin/sh -c sudo -u [username], using basic string
template substitution for the username. An attacker with either direct access
to the memory backing the username string or by setting the current username
to a malicious value could use this to inject commands running with the same
privileges as tssentineld.
This vulnerability is fixed in Tailscale version 1.94.0 and newer.
What was the impact?
Malicious local users that can manipulate their username or manipulate memory of tssentineld can execute arbitrary commands as root.
Who was affected?
The macOS standalone variant from 1.84.0 to 1.92.3, when configured via MDM to enable the AlwaysOn.Enabled policy is affected.
tssentineld is only activated on clients managed by MDM and employing the
AlwaysOn.Enabled policy and requires admin permission to install and
activate. Memory manipulation to inject a malicious command requires a separate
vulnerability or existing root access. The user may, however, modify their username
in such a way that tssentineld could execute arbitrary shell commands with elevated
privileges.
The macOS package available from the App Store does not support the installation of launchd daemons and is not affected.
What do I need to do?
If you are using the AlwaysOn.Enabled policy with standalone macOS clients, update to version 1.94.0 or newer.
TS-2025-008
Description: Nodes without --statedir or TS_STATE_DIR failed to enforce signing checks in tailnets with Tailnet Lock enabled.
What happened?
In tailnets where Tailnet Lock is enabled, unsigned nodes running the tailscaled daemon (for example, on Linux) without specifying a --statedir or --state 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.
When Tailnet Lock is enabled, Tailscale nodes will only communicate if their node keys have been signed by a trusted signing node.
The set of trusted signing nodes is tracked by the tailnet key authority (TKA). 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.
The TKA state is stored on disk in the state directory. Prior to 1.90.8, this was the only storage option.
- If you use the macOS, Windows, iOS, Android, and tvOS clients, the state directory is set automatically.
- If you run the
tailscaleddaemon, the state directory is set by the--statediror--stateflags. - If you use the default systemd unit files distributed with the official Tailscale
deb,rpm, andtar.gzpackages, the--stateflag is set automatically. - If you use Tailscale in Docker or Kubernetes, the state directory is set by the
TS_STATE_DIRenvironment variable.
If tailscaled was started without a state directory (--statedir, --state, and/or TS_STATE_DIR 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.
What was the impact?
There is no indication of this issue being exploited in the wild.
The bug allowed communication between two or more unsigned nodes, each running without a state directory, even though Tailnet Lock was enabled.
While the bug is present across many versions, the risk of exploitation is low. It was not possible for an unsigned node without a --statedir 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.
Who was affected?
The vulnerability only manifests when all three of the following conditions are met:
- Tailnet Lock is enabled in the tailnet,
- At least two nodes were running the
tailscaleddaemon without the--statedir/--stateflags, or without theTS_STATE_DIRenvironment variable, and - At least one of the node keys was not signed.
This bug was present in all Tailscale clients from the introduction of Tailnet Lock, and is fixed in version 1.90.8.
You can tell if a node is affected by this issue by running tailscale lock status.
If the output says Tailnet Lock is NOT enabled but Tailnet Lock is enabled in your Tailnet, the node is not enforcing signing checks correctly.
Alternatively, you can look for the following text in your client logs:
network-lock unavailable; no state directory
(The pre-release name for Tailnet Lock was "network lock", which still persists in parts of the codebase.)
What do I need to do?
If you don't use Tailnet Lock, no action is required.
If you do use Tailnet Lock:
-
Review the configuration of any nodes that run the
tailscaleddaemon. Specifically, check the startup parameters for thetailscaledservice. Any nodes runningtailscaledwithout a state directory are potentially vulnerable until upgraded. -
Upgrade all nodes running the
tailscaleddaemon to 1.90.8 or later. Alternatively, set a state directory by:- Adding the
--statedirflag if you run thetailscaleddaemon, or - Adding the
TS_STATE_DIRenvironment variable if you run Tailscale in Docker or Kubernetes.
- Adding the
In version 1.90.8 and later, nodes without a state directory will now store the TKA in memory and enforce Tailnet Lock signing requirements.
However, nodes that store TKA in memory must re-fetch the complete TKA from the coordination server whenever they start. We strongly recommend setting a state directory for all nodes, allowing them to store the TKA on disk and eliminate the startup control plane dependency.
TS-2025-007
Description: A one-off auth key could be reused from multiple devices
What happened?
A time-of-check/time-of-use (TOCTOU) issue allowed multiple nodes to register using the same one-off auth key. These registration attempts would have to happen at approximately the same time to succeed.
The Tailscale coordination server relies on database transactions to ensure consistency and prevent race conditions. The API handler for node registration requests uses a read transaction to validate the request, including the auth key, and then a separate write transaction to complete the registration. One-off auth keys are invalidated during the write transaction stage. Previously, if two registration requests came in at the same time they would both successfully validate the auth key during the read transaction and proceed to register the node. We fixed the API handler to re-validate the auth key during the write transaction stage to catch this race condition.
What was the impact?
A one-off auth key could be reused multiple times to register multiple nodes, rather than just one.
Who was affected?
Tailnets using one-off auth keys through automation. All nodes would have to obtain a legitimate auth key for the tailnet. Malicious nodes cannot abuse this issue to join the tailnet.
Tailscale audit logs do not have enough information to detect this race condition happening. We plan to improve our audit logs to make detection of incidents involving auth keys easier in the future.
What do I need to do?
No action is required. Tailscale has deployed a fix to the coordination server as of 2025-11-07.
Credits
We would like to thank madisp for reporting this issue.
TS-2025-006
Description: A potential access control logic issue affected shared subnet router nodes between tailnets.
What happened?
Tailscale nodes that are subnet routers and shared with other tailnets did not enforce protocol filters in ACLs. For example, a subnet router with an IP grant of "udp:1234" in the policy file would allow TCP, UDP, and any other protocol connections to port 1234. This bug was fixed in our control plane and does not require any update.
The Tailscale Control Plane performs a process known as network map trimming to ensure that only nodes with authorized access to each other appear in their respective clients.
As part of this process, the Control Plane transforms ACLs for nodes that serve as subnet routers, exit node, or app connector and are shared externally with other tailnets to constrain the access of external tailnet members to only the shared node and prohibit their access to the routed subnets.
This filtering contained a bug, producing ACLs for these nodes that omitted their IP Protocol number information entirely. This caused those nodes to accept connections using arbitrary protocols from both local and external tailnets the node was shared with. The src/dst restrictions, as well as port restrictions still applied, so these nodes were not accessible broadly.
For ACL rules that relied on protocol-based filtering, such as imcp:* this would have allowed connections from the source using arbitrary protocols to the destination.
What was the impact?
Local and external tailnet members with existing access to subnet routers that were shared externally would have been able to exceed their authorized access and establish connections using arbitrary protocols to these nodes.
Local and external members who were not included in the source of the impacted ACL groups would not have been able to access impacted nodes using these rules.
There is no indication of this issue being exploited in the wild. The exposure is limited to nodes that were intentionally shared to another tailnet.
Who was affected?
Tailnets with nodes that are subnet routers, that were also shared with external tailnets, and whose ACLs for these nodes relied on protocol filtering were affected.
This bug was present in all Tailscale clients from the introduction of these features, and was fixed for all clients through the Tailscale control plane on October 29th 2025.
What do I need to do?
No action is required. Tailscale has deployed a fix to the control plane as of 2025-10-29.
Credits
We would like to thank Thariq Shanavas for reporting this issue.
TS-2025-005
Description: Logging of MDM-provided auth keys
What happened?
A change in Tailscale version 1.84.0 on macOS and iOS caused all MDM-provided configuration values to be logged and uploaded to the Tailscale log server. One of the possible MDM values is an auth key used to automatically register the node. This resulted in the Tailscale log server storing user auth keys along with other client logs.
The logs collected by the Tailscale log server are only accessible to Tailscale employees, so no auth keys were leaked to potential attackers.
Tailscale version 1.86.4 redacts the auth key, and other textual values, before logging them.
What was the impact?
MDM-provisioned auth keys were uploaded to the Tailscale log server. No keys have leaked outside of Tailscale infrastructure. Auth keys provided on the CLI or using environment variables were never logged.
The impact depends on the type of auth key used:
- One-off auth keys are used and invalidated when the node is registered; there is no risk to your tailnet
- Reusable auth keys could be used again to register nodes if stolen
- Pre-signed auth keys for Tailnet Lock are like reusable auth keys, but can also register nodes that don't need to be signed by another signing node in the tailnet
Who was affected?
Customers using MDM to distribute auth keys, with macOS and iOS clients running Tailscale versions between 1.84.0 and 1.86.2, are affected.
What do I need to do?
If you don't use MDM to distribute auth keys to your devices, no action is needed.
If you do distribute auth keys with MDM, upgrade all macOS and iOS nodes to Tailscale version 1.86.4 or later. Additionally, if you distribute reusable auth keys, or pre-signed auth keys for Tailnet Lock, we recommend that you rotate these keys.
TS-2025-004
Description: Tailnets using shared public email providers
What happened?
On May 22, 2025 our Reddit community gave us the necessary kick to address an issue with handling shared public email provider domains ("shared domains"). We mitigated the risk for new tailnets being created on previously unknown shared domains by enabling user approval by default. This issue affects only a small portion of our user base, and this bulletin provides some background, mitigation steps, and our future plans.
Background
Tailscale users are mapped to tailnets by their email address domain (with a
few exceptions*). This means that [email protected] and [email protected]
can both log in to tailnet example.com. We chose this default behavior because
it reduces onboarding friction for new users and tailnet admins.
The downside of this default behavior is that if a user's email address comes from a shared domain, multiple unrelated users may be able to join the same tailnet without realizing that others are in their tailnet too.
Tailscale has a workaround for this scenario: we flag known shared domains in
our database. For example, when [email protected] logs in for the first time, we
create a personal tailnet named [email protected] for them instead of adding
them to one giant gmail.com tailnet. If there is an existing shared domain
tailnet, we "decompose" it - break it up into new personal tailnets for each
user with only their nodes. Very popular email providers, like Gmail or Yahoo,
have been decomposed from the very beginning.
This workaround has an obvious flaw: we can't flag all shared domains in our database proactively, because there is no authoritative list of such domains and new providers can show up at any time. So far we have patched over this flaw by retroactively flagging new shared domains when users report them to us. This has been convenient for ease of onboarding new users, especially users on corporate domains.
* We use special OIDC claims to map logins to tailnets on Google Workspace
(hd claim) and Microsoft Entra (tid claim).
What changed
On May 22, 2025 a post on Reddit made the severity of this issue more obvious. The poster was using a previously unknown shared domain. We flagged the new shared domain and decomposed the tailnet.
To mitigate the potential risk for tailnets on shared domains, we enabled user approval by default for all new tailnets. This way, even if unexpected users log in using a shared domain that is not decomposed yet, an administrator will have to approve them first. We did not change the setting for any existing tailnets to avoid breaking any workflows.
Since May 22nd, we also decomposed 130 additional tailnets based on signals like: number of users, payment plan, recent activity, whether they have a Google Workspace or a Microsoft Entra tenant, and basic online research. Before May 22nd, we had already flagged and decomposed 534 shared domains, many proactively, but some in response to support tickets.
What we're doing next
We have certainly dug ourselves into a hole here. There are various public lists of shared domains, but it is tricky to figure out which existing tailnets are meant to be single-user and which are not. There are shared email hosting providers, customer emails created by ISPs, university emails, disposable email providers, etc. In all cases a tailnet could be a legitimate corporate tailnet for the company or university, and decomposing the tailnet could break their setup.
There are several planned actions and projects that should improve the situation:
- Short-term
- Proactively flag more shared domains that don't have tailnets yet, using public email provider lists and the Public Suffix List.
- Reach out to admins of tailnets that are potentially on shared domains, but where we can't be certain, with advice on how to protect and audit their tailnets.
- Medium-term
- Mark any new domain coming through a Google or Microsoft login as shared if it's not associated with Google Workspace or a private Microsoft Entra tenant.
- Prompt owners of existing tailnets like the above to enable User Approval on next login. Today this is ~1.7% of all tailnets.
- Create a process for unflagging a shared domain through a support ticket and DNS ownership verification in case of false positives.
- We are discussing changing the default ACL in new tailnets, but no decision has been made yet.
- Long-term: a large identity model change has been in the works for roughly a year that, among other things, will make all new user registrations create a personal tailnet instead of a domain-wide tailnet by default.
What was the impact?
There are two potentially risky scenarios with shared domains: malicious users and malicious admins.
Malicious users could join a tailnet of an unsuspecting user and access exposed ports on that user's nodes. Tailnet ACLs could limit that impact, but default ACLs allow access to all ports on all nodes. Note that Tailscale SSH is not allowed between nodes of different users, so a malicious user would need to exploit some other software on a victim's node to gain access or information. Also note that the free plan of Tailscale is limited to 3 users.
Malicious admins could create a tailnet on a shared domain and wait, or social-engineer victims to join it. Once victims join the tailnet, a malicious admin could access all open ports on victims' nodes, and set up a subnet router to intercept their traffic. A malicious admin could also set up their own DNS server for the tailnet to record and spoof DNS responses.
We are not aware of any instances of either of these scenarios happening.
Who was affected?
Users of 664 known shared domains out of a total 166,488 unique domains we've seen across all tailnets may have had their nodes exposed to other users with the same email domain. 534 of these shared domains have been been decomposed throughout Tailscale's history and not recently.
There may be other tailnets using shared domains that we haven't discovered yet.
Who was not affected?
The following categories of users are not affected:
- Users with custom email domains (corporate or personal)
- Users with custom OIDC providers
- GitHub users, including personal and org tailnets
- Owners of tailnets with User Approval or Device Approval enabled
- Owners of tailnets with Tailnet Lock enabled
- Users of very popular email providers, like
gmail.com,outlook.com,yahoo.com,protonmail.com, and others - Users with custom restrictive ACLs that avoid
autogroup:memberand other broad selectors insrcclauses
What do I need to do?
If your tailnet name in the top-left corner of the Admin Console is an email address rather than a bare domain, no action is needed.
If you are in a tailnet on a shared domain:
- Contact support to request your tailnet to be decomposed.
- If you're the tailnet owner, review the list of users in your tailnet and audit logs for evidence of any suspicious activity.
- If you're the tailnet owner and don't want to decompose your tailnet, enable user and/or device approval.
If you are in a tailnet on a domain that was wrongfully decomposed, contact support to reset your tailnet.
Timeline
- March 2019: Tailscale started, Google and Azure AD (now Entra) authentication implemented
- December 2019
- decision to maintain a list of shared domains was made
- first shared domain hardcoded -
gmail.com - Tailscale launched to a small set of users
- November 2020: Node sharing released
- January 2021: the hardcoded list of shared domains moved into a database table, tools created for the support team to decompose new shared domains
- June 2021: GitHub authentication added
- March 2023: Custom OIDC authentication added
- April 2023: Passkey authentication added
- April 2023: Apple authentication added
- May 2023: External user invites added
- This was primarily the point at which creating a tailnet for email domains stopped being necessary. Multiple users could join a shared tailnet by an invitation to access each other's nodes, even on personal accounts from shared domains.
- May 2025:
- May 22nd: Reddit user posted about an unexpected member of their tailnet
- May 22nd: User approval enabled by default for new tailnets
- May 23rd-27th: 130 shared domain tailnets identified and decomposed
TS-2025-003
Description: Insecure non-constant time comparison in DERP server mesh authentication
What happened?
Tailscale's DERP (Designated Encrypted Relay for Packets) servers provide connectivity between Tailscale nodes in the event that they cannot mutually communicate due to network restrictions. DERP servers deployed in the same region communicate using a private mesh API to coordinate client connections amongst themselves. These private mesh connections authenticate using a pre-shared secret key.
The DERP servers previously used an insecure non-constant time comparison when verifying the mesh authentication secret. This would have allowed an attacker to discover the mesh secret by performing a side channel timing attack.
The issue was present since the introduction of DERP meshing and patched on May 21, 2025. We have updated all Tailscale-managed DERP servers and rotated their mesh secrets.
Who was affected?
All Tailscale-operated DERP servers and Tailscale users who operate their own custom DERP servers with more than one server per region.
What was the impact?
An attacker who discovered the mesh key could not see any plaintext traffic between nodes, since all traffic is end-to-end encrypted.
An attacker with mesh access would have been able to enumerate all peers connected to a DERP server, including their WireGuard public key and their source IP address and port.
An attacker with mesh access would have been able to perform a denial-of-service attack (DoS attack), prohibiting a node’s keys on any DERP servers by forcing disconnects of meshed DERP servers by using the ClosePeer API.
We have no evidence to indicate any abuse of this issue.
What do I need to do?
If you operate your own custom DERP servers in a mesh setup, you should update to the latest version and rotate any mesh keys that were previously in use.
TS-2025-002
Description: Privilege escalation in proxy-to-grafana via header spoofing
What happened?
The Tailscale Grafana proxy is a HTTP reverse proxy for Grafana that annotates requests with X-Webauth-* headers bearing the requesting user's whois-based Tailscale identity.
The Grafana proxy is intended to be used in combination with Grafana's session-based authentication using cookies issued in response to requests made to /login to authenticate subsequent requests to other endpoints.
When configured to use session-based authentication, Grafana's /api/ routes will continue to accept X-Webauth-* headers for authentication. Previous versions of the Grafana proxy did not strip these X-Webauth-* headers from API requests allowing them to be forged by a malicious tailnet node.
The issue was present since the initial release of the Grafana proxy, and was patched on May 15th, 2025. The Grafana proxy now strips X-Webauth-* headers from all incoming requests.
Who was affected?
Tailnets using Grafana in combination with the Grafana proxy to authenticate users.
What was the impact?
Grafana instances protected by the Grafana proxy would have been vulnerable to privilege escalation via HTTP request header forgery from members of their tailnet.
What do I need to do?
Update to the latest Grafana proxy by running go install tailscale.com/cmd/proxy-to-grafana@latest
Credits
Thanks to Yeongrok Gim for reporting this issue.
TS-2025-001
Description: Potential for continued admin console access past inactivity timeout
What happened?
The admin console session timeout works by recording tailnet-specific activity timestamps on login and from browser requests triggered by user activity. Previously the admin console also erroneously considered the act of switching between multiple tailnets to be a login and recorded a fresh timestamp for the user in the destination tailnet while switching.
For tailnets whose users were also members of other tailnets with less strict inactivity timeouts, these users may have been able to continue their access to the admin console for longer than expected if they switched between tailnets and did not time out of the less restrictive tailnet.
The issue was present since inactivity timeout was initially released in August 2024, and was fixed in production on March 7th, 2025. A user who switches to a tailnet in which their session has already expired will be logged out and redirected to the login page.
Who was affected?
Tailnets with admin console session timeout configurations and users who are members of other tailnets with less strict session timeout configurations.
What was the impact?
Users of tailnets with strict admin console session timeouts may have been able to continue their access to the admin console past expected timeouts by switching to and from other tailnets in the admin console whose console configurations were less strict.
What do I need to do?
No action is required.
TS-2024-013
Description: Potential for Tailscale SSH recording failures
What happened?
Tailscale SSH recording deployments that enforce SSH recording
using enforceRecorder could fail to record session activity in several
situations.
Failure to write to the storage backend
If tsrecorder instances were unable to write to their configured storage, SSH
sessions would be allowed to execute for a few seconds (typically under one or
two) while the first output bytes failed to write.
A tsrecorder instance can fail to write to its configured storage for many
reasons, including:
- Misconfigured IAM permissions when using S3 for storage.
- Misconfigured file permissions when using the local filesystem for storage.
- Insufficient free space when using the local filesystem for storage.
tsrecorder now exercises the full set of required storage actions on startup.
Unreachable tsrecorder after a session is established
If tsrecorder instances became unreachable after a session had started, the
SSH session would take several minutes to terminate. This could happen when
tsrecorder went offline or when ACLs were updated to restrict access to
tsrecorder nodes.
The Tailscale client now detects tsrecorder unreachability within 30 seconds
and terminates the connection.
Who was affected?
Users of Tailscale SSH recording with enforceRecorder option and with
tsrecorder and Tailscale client versions prior to 1.78.0.
What was the impact?
Users connecting over Tailscale SSH to nodes that enforce session
recording via enforceRecorder ACL flags would have been able to execute
commands briefly before having their access terminated due to recording
failures.
What do I need to do?
Update tsrecorder instances and Tailscale clients to version 1.78.0 or later.
TS-2024-012
Description: Tailscale Funnel abused for phishing
What happened?
A malicious user abused Tailscale Funnel to host a phishing page targeting Facebook users. This user created multiple free Tailscale accounts to use as an obfuscation/anonymity proxy for their VPS instance hosting the phishing page.
We received the first report about a phishing page on September 23rd, 2024, and took down the Funnel page the same day. We received the second report on October 1st, 2024, for the same phishing page on a different Tailscale account. We took down the second page, added detection for new similar pages, and repeatedly shut down new attacker accounts as they were created. After a few more attempts, the attacker stopped creating new accounts.
Who was affected?
232 unique IP addresses accessed the attacker's Funnel nodes. Of those, 87 IP addresses made more than one request, suggesting a possible phishing form submission.
What was the impact?
Some Facebook users could have been phished for their credentials. Since Tailscale Funnel proxies can only see encrypted TLS traffic, we cannot confirm whether anyone was successfully phished.
What do I need to do?
Don't use Tailscale Funnel for phishing.
TS-2024-011
Description: SCIM group name disclosure via the ACL editor
What happened?
The ACL editor in the admin console did not check SCIM group names in the ACL rules against the tailnet name. This allowed tailnet A to use SCIM groups from tailnet B in their ACL rules. A malicious user in tailnet A could not gain access to target tailnet B this way. However, they could use the fact that ACLs get saved without warnings to learn about valid SCIM group names in other tailnets.
This issue was fixed on July 19th, 2024. A user trying to save ACLs with SCIM group names from other tailnets will always receive a warning that these groups do not exist, even if they do exist in other tailnets.
Who was affected?
None of the existing tailnets' ACLs appear to use SCIM group names from other tailnets maliciously. A handful of customers used the wrong SCIM group names from their production tailnets in their test tailnets by accident.
What was the impact?
A malicious user could learn about SCIM group names used in other tailnets.
What do I need to do?
No action is required.
TS-2024-010
Description: Accidental ACL edits due to browser caching
What happened?
When switching tailnets in the admin console, an Admin user could overwrite the ACLs of one tailnet with pending changes to ACLs from another tailnet.
When a user has unsaved ACL changes in the admin console, those changes are cached in browser storage. If this user is a member of multiple tailnets, tailnet A and tailnet B, and is editing ACLs for tailnet A, using the tailnet switcher in the top-right corner of the page would not clear the cached ACL changes correctly. In some rare cases, saving ACLs of tailnet B after the switch would use the cached ACL contents from tailnet A.
A user can be an Admin in multiple tailnets when they use GitHub to log in, and are a member of GitHub organizations, or the user is invited to another tailnet and granted the Admin role.
Tailnet switching in the admin console was added on May 22nd, 2023. We fixed this bug on July 17th, 2024.
Who was affected?
Any user who is an Admin in multiple tailnets and edited ACLs in the admin console between May 22, 2023 and July 17th, 2024 could trigger this bug after switching the active tailnet.
What was the impact?
An Admin user could overwrite the ACLs of one tailnet with ACLs from another tailnet.
What do I need to do?
If you are an Admin of multiple tailnets using the same login name, review the ACLs in your tailnets for correctness.
TS-2024-009
Description: Potential for API credential disclosure over plaintext HTTP
What happened?
The Tailscale API is primarily accessible over TLS-encrypted HTTP at
api.tailscale.com. It also has a limited plaintext HTTP handler to serve HTTP
to HTTPS redirects.
Browsers that connect over plaintext HTTP do not send cookies marked as Secure
to prevent them from being disclosed to network intermediaries.
However, API clients that connect using plaintext HTTP and send requests with authentication tokens in headers have no such protections to prevent disclosure.
Before June 26, 2024, the Tailscale API did not reject credentialed plaintext API requests and instead served them HTTP 302 redirects as it would to browsers. Typical HTTP client libraries handle redirects transparently, and consequently, the user would not necessarily know their credentials had been exposed.
Starting on June 26, 2024, the Tailscale API now returns errors for all plaintext HTTP requests that include credentials. Additionally, the Tailscale API now automatically revokes API keys that it observes sent over HTTP and notifies Tailnet security owners of this action.
Who was affected?
Any Tailscale API client that connected over plaintext HTTP using credentials before June 26, 2024.
What was the impact?
API clients that connected over plaintext HTTP before June 26, 2024 would have exposed their credentials to network intermediaries, risking them to theft and replay.
What do I need to do?
No action is needed at this time.
Credits
Thanks to Joachim Viide for reporting this issue.
TS-2024-008
Description: Partial loss of audit and network flow logs
What happened?
An integer overflow in our logs processing service led to some customer logs to be non-deterministically dropped with a probability of 14%. The overflow condition first exhibited on June 7th, 2024 at 20:45 UTC and was detected and resolved by June 14th, 2024 at 00:40 UTC.
Who was affected?
All tailnets that rely on audit and network flow logs have been affected.
What was the impact?
The 14% chance of dropped log entries affects storing of logs such as configuration audit logs and network flow logs. While logs can be retrieved for the timeframe that the overflow bug was active, some fraction of the entries may be missing.
What do I need to do?
No action is needed at this time.
We fixed the bug, added additional error checking, and deployed both to the logs processing service.
TS-2024-007
Description: Incorrect DNS resolution with split DNS on macOS and iOS
What happened?
On Tailscale macOS and iOS clients with split DNS configurations (like App
Connectors or Restricted
Nameservers), lookups of bare tailnet node names
could in rare cases return incorrect answers. For example, if a node mynode
and an App Connector for *.example.com exist on a tailnet, DNS lookups for
mynode could return the answer for mynode.example.com instead of the local
tailnet IP. This mis-configuration is intermittent, and most often triggers for
a few seconds when switching device networks (for example from Wi-Fi to a phone
hotspot).
We fixed this bug in client version 1.68.0, and notified the security contacts of potentially affected tailnets over email.
Who was affected?
All tailnets that use App Connectors or Restricted Domains, and have macOS or iOS nodes could have been affected.
This bug is usually intermittently-triggered when switching networks in our
experience. Only lookups of bare domains, like mynode but not
mynode.mytailnet.ts.net, are at risk.
Note that not all split DNS domains are dangerous. Only domains where an attacker can choose their FQDN to match a node name, and controls the destination to receive non-TLS traffic could be abused.
We are not aware of any active exploitation of this vulnerability.
What was the impact?
For a split DNS domain example.com, an attacker with control over
mynode.example.com can impersonate a non-TLS server running on node mynode
on the tailnet. This attack is opportunistic and passive - it relies on the
user connecting to mynode using its bare domain and cannot be forced
remotely.
What do I need to do?
Upgrade your macOS and iOS clients to 1.68.0 or later.
TS-2024-006
Description: Tailnet SSO provider migration impacting invited users
What happened?
When tailnets are created, they are associated with an SSO provider such as Google or Microsoft, requiring all members of the tailnet to authenticate using that provider. In addition, Tailscale also supports inviting external users to tailnets to allow sharing with contractors, friends, or other collaborators who may use a different SSO provider than that of the inviting tailnet to log in to Tailscale.
Customers with an existing tailnet who wish to use a different SSO provider can request to migrate via customer support. The internal tool used to perform these migrations previously migrated the SSO provider for all members of a tailnet, including those of invited external members.
We fixed this internal tool to migrate direct tailnet members, excluding invited members on May 20, 2024.
We reverted the erroneous SSO provider changes and notified affected users on May 23, 2024.
Who was affected?
55 users were invited external members of tailnets whose SSO provider was subsequently migrated prior to May 20, 2024. We have notified the security contacts for the tailnets where users were affected by this incident.
What was the impact?
Users whose SSO providers were erroneously migrated would have been unable to log in to Tailscale during this time, as their SSO source would differ from the one on record.
What do I need to do?
No action is needed at this time.
TS-2024-005
Description: Insufficient inbound packet filtering in subnet routers and exit nodes
What happened?
In Tailscale versions earlier than 1.66.0, exit nodes, subnet routers, and app connectors, cou
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.