TS-2026-009:Tailscale SSH 中的参数处理不安全导致允许 Root 访问
TS-2026-009: Insecure argument handling in Tailscale SSH permitted root access

原始链接: https://tailscale.com/security-bulletins

Tailscale 已修复 1.66.0 版本之前的漏洞,该漏洞可能允许未经授权的局域网(LAN)入站连接访问 Tailnet 中的节点。此问题主要影响使用宽松 ACL(如 `src: "*"`)的 Linux 系统出口节点、子网路由器和应用连接器。 在特定配置下,与数据包转发节点处于同一局域网的恶意攻击者可以绕过标准访问控制,将流量发送到其他 Tailnet 节点。 **缓解措施及所需操作:** * **更新:** 将所有 Linux 出口节点、子网路由器和应用连接器升级至 Tailscale 1.66.0 或更高版本。 * **ACL 变更:** Tailscale 已重新定义 `src: "*"` ACL 规则,默认排除外部流量。如果合法网络需要之前的“全部允许”行为,用户应改为使用新的 `autogroup:danger-all` 简写。 * **状态防火墙:** Linux 节点已实施新的状态包过滤功能,以阻止未经请求的入站连接。 目前暂无利用此漏洞的报告。未使用包含外部 IP 范围的自定义 ACL 的 Tailnet 不受影响。

```Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 TS-2026-009:Tailscale SSH 中不安全的参数处理导致了 root 权限泄露 (tailscale.com) 7 分,作者:jervant,22 分钟前 | 隐藏 | 过往 | 收藏 | 1 条评论 帮助 tptacek 3 分钟前 [–] 这是一种非常古老且经典的漏洞,至少可以追溯到 AIX 3 时代。很高兴看到他们还在制造这种经典的漏洞。(如果你拥有 Tailscale ACL 中某台主机的 SSH 访问权限,你就可以通过 `-i` 参数登录并获得 root 权限。) 回复 考虑申请 YC 2026 年秋季班!申请截止日期为 7 月 27 日。 准则 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索: ```
相关文章

原文

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, could allow inbound connections to other tailnet nodes from their local area network (LAN). This vulnerability only affects Linux exit nodes, subnet routers, and app connectors in tailnets where ACLs allow "src": "*", such as with default ACLs.

Tailscale version 1.66.0 fixes the vulnerability. Additionally, a server-side update changes the interpretation of "src": "*" to mitigate the issue specifically for exit nodes.

Special thanks to Hakan Ergan for reporting a similar concern that led us to discover this vulnerability.

Who was affected?

This affected the following nodes using Tailscale version 1.65 or earlier:

  • Exit nodes on Linux
  • Subnet routers on Linux
  • App connectors on Linux
  • Regular nodes on all platforms connecting to the above nodes

Tailnets with custom ACLs that do not use "src": "*" or any other value that includes external IPs were not affected.

We are not aware of any active exploitation of this vulnerability.

What was the impact?

Devices outside of the tailnet, but on the same LAN as an exit node, subnet router, or app connector could connect to ports on tailnet nodes that are allowed by ACLs.

What do I need to do?

Upgrade the following nodes to 1.66.0 or later:

We recommend enabling auto-updates and updating all nodes to the latest version, but it is not required to mitigate this vulnerability.

A server-side change mitigated this vulnerability for other types of affected nodes.

Technical details

Below, we refer to exit nodes, subnet routers, and app connectors as packet-forwarding nodes, because the details apply to all of them. Specific types of packet-forwarding nodes are mentioned explicitly where their behavior is different.

Before 1.66.0, packets between regular nodes and destination hosts behind packet-forwarding nodes were filtered based on source/destination IP as specified in tailnet ACLs. Specifying "src": "*" in ACLs is equivalent to "src": ["0.0.0.0/0", "::/0"], meaning any IP address. This allowed source IPs outside of the tailnet to send packets to tailnet nodes via a packet-forwarding node. This could be abused by malicious LAN hosts to connect into the tailnet using a known tailnet node IP.

The attack only works on a LAN because:

  • it relies on next-hop routing, which only works in a LAN
  • destination IPs are in the subnet router's approved range, or in the CGNAT range 100.64.0.0/10, which are not routable over the Internet.
Attacks

Here are several attack scenarios.

Packet-forwarding node on an untrusted LAN.

diagram showing a LAN machine connecting to a victim node

A malicious host 10.0.0.1 on the same LAN as the packet-forwarding node 10.0.0.2 could craft packets with destination IP of a tailnet node 100.64.0.1 (using a command like ip route add 100.64.0.1/32 via 10.0.0.2 dev eth0) and send them to the packet-forwarding node. The packet-forwarding node would accept them and forward them to the victim node. The victim node would see a packet from 10.0.0.1 and accept it if the tailnet ACLs allow this source IP.

This scenario is very similar to a legitimate use-case of site-to-site networking, where two subnets are bridged using Tailscale subnet routers and the flag --snat-subnet-routes=false.

Malicious shared exit node

diagram showing a malicious exit node connecting a the victim node

A malicious exit node 100.64.0.4 from tailnet A could craft packets with destination IP of tailnet B node 100.64.0.3 and any source IP other than 100.64.0.4. Due to the built-in quarantining of shared nodes, packets from 100.64.0.4 are rejected.

Mitigations

We implemented 3 separate mitigations for these attacks.

Redefine "src": "*" in ACLs

While * is a convenient shorthand in ACLs, Tailscale users almost never need to allow connections from any IP. In most cases users intend * as "all other nodes in my tailnet". As a mitigation for this vulnerability, we redefined * in src section of ACLs to include:

  • all tailnet nodes
  • all IPs from approved subnet routes

The inclusion of IPs from approved subnet routes is needed for the site-to-site networking setup.

For users that need the old semantics of * we added a new autogroup:danger-all, which matches the old definition of *.

Stateful packet filtering on packet-forwarding nodes

On Linux packet-forwarding nodes we added stateful packet filtering. This means that these nodes keep track of forwarded connections and only allow return packets for existing outbound connections. Inbound packets that don't belong to an existing connection are dropped.

Because routing is implemented differently on non-Linux platforms, this mitigation is only necessary on Linux.

Stateful filtering is enabled by default, except for existing subnet routers that set --snat-subnet-routes=false. You can disable stateful filtering using tailscale up --stateful-filtering=false.

Client-side quarantining of shared nodes

Quarantining of shared nodes was implemented by a packet filter sent from the Tailscale control plane. This packet filter instructs nodes to drop any inbound connections from the source IP of the shared node. To prevent malicious shared exit nodes from crafting packets with different source IPs, additional client-side quarantining logic was added. The 1.66.0 and later clients reject all inbound connections from quarantined nodes, regardless of their source IP. This is similar to how the "shields up" mode works within the tailnet.

联系我们 contact @ memedata.com