CVE-2024-3661 — TunnelVision (DHCP option 121 VPN traffic leak)
A malicious or compromised DHCP server can hand a client a routing table via option 121 (Classless Static Routes) that overrides the VPN's catch-all tunnel route. Traffic the user believes is encrypted instead leaves the LAN gateway in cleartext. This is not a bug in any single VPN product — it is the interaction between DHCP, the host's routing stack, and how almost every VPN client installs its tunnel route.
TL;DR
- Disclosed 2024-05-06 by Leviathan Security Group (Lizzie Moratti, Dani Cronce). CVSS 7.6, Adjacent + Unauthenticated.
- Attack class, not a single software bug — no version of WireGuard, OpenVPN, or Tailscale to "upgrade to". The fix lives in the network stack and the deployment shape.
- Affects every VPN client running on a host that respects DHCP option 121: Linux, macOS, Windows by default; iOS and Android per platform posture.
- VPN endpoints (the server side) are not vulnerable. The exposure is on the client side, on whatever LAN it joins.
- No software fix is straightforward — it's the network stack. Mitigation is configuration: network namespaces, route-table policy, or "don't trust the LAN you're on".
- This is not CISA-KEV listed — it's a designed-in attack class requiring active LAN adjacency. Risk is real for laptops and phones on hostile Wi-Fi.
At a glance
| CVE ID | CVE-2024-3661 |
|---|---|
| Common name | TunnelVision |
| Severity | High (CVSS 7.6) |
| CVSS 3.1 vector | AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L |
| CWE | CWE-306 (Missing Authentication for Critical Function) · CWE-501 (Trust Boundary Violation) |
| CISA KEV listed | No — attack class, not exploited-as-malware |
| Disclosed | 2024-05-06 |
| Disclosed by | Leviathan Security Group |
| Primary remediation | Network-namespace isolation (Linux), routing-policy enforcement, or trusted-LAN-only operation — not a patch |
What DHCP option 121 actually does
DHCP option 121 ("Classless Static Routes", RFC 3442) is a legitimate feature. It lets a DHCP server tell a client: "for these specific subnets, use this gateway". It exists so split-tunnel deployments and corporate networks can hand out routing policy without rebuilding each client by hand.
The catch: routes pushed via option 121 are typically more specific than the catch-all 0.0.0.0/0
route that a VPN client installs over its tunnel interface. Linux, macOS, and Windows routing tables all prefer
the more-specific match. So a DHCP server that hands out, say, 1.0.0.0/8 → 192.168.x.1 through
240.0.0.0/4 → 192.168.x.1 can carve up the entire IPv4 space into routes that bypass the tunnel —
while the VPN client still believes it is routing everything through tun0. No alarms, no kill-switch
trigger, no log line. The tunnel is up; it just isn't carrying the traffic.
Which VPNs and OSes are affected
| Platform | Default posture | Mitigation |
|---|---|---|
| Linux (any VPN client) | Vulnerable | Network namespace, or explicit routing-table policy |
| macOS | Vulnerable in default config | System Settings → Network policy; force-all-via-VPN where the client supports it |
| Windows | Vulnerable in default config | Firewall rule blocking VPN-adjacent routes; Table=off on WireGuard configs |
| iOS | Less exposed in stock config; behaviour depends on VPN client | Per Apple's response — varies by client |
| Android | Vulnerable; varies by version | "Always-on VPN" + "Block connections without VPN" reduces but does not fully eliminate |
| VPN server side (the endpoint you host) | Not vulnerable | n/a — the attack is purely client-side, on whatever LAN the client joins |
| Specific products: WireGuard, OpenVPN, IPsec, Tailscale, all major commercial VPNs | All affected when the client OS honours option 121 | Same as the host OS row above |
Why "patch your VPN client" doesn't fix this
There is no version of WireGuard, OpenVPN, or Tailscale you can upgrade to that closes TunnelVision on its own. The behaviour is correct at every layer of the stack: DHCP is doing what the RFC says, the kernel routing table is doing longest-prefix match the way it's supposed to, and the VPN client genuinely did install its catch-all route. The exposure is in the seam between those three things — which means the fix has to be applied at the network-stack layer (routing policy) or the deployment layer (network namespaces, isolated routing tables, or "don't accept option 121 at all on this interface").
That's why TunnelVision is genuinely awkward: it's a homework-assignment fix per platform, not a apt upgrade.
Mitigations
- Linux — most robust: run the VPN client inside a network namespace. DHCP routes from the host's namespace don't apply to the namespace running the tunnel. Pattern:
ip netns add vpn, move the physical interface or use a veth pair, run the VPN client inside the namespace, and route all application traffic through that namespace. - Linux — secondary: explicit firewall rules dropping any non-tunnel-bound egress, with route-table priority pinned to
tun0. Less foolproof than namespacing because it relies on you having enumerated every route the attacker can push. - macOS: in System Settings → Network, enable "Send all traffic over VPN connection" where the client exposes it, and disable DHCP option 121 acceptance on untrusted interfaces.
- Windows: set the WireGuard config to
Table=offand install routes manually, or use a Firewall rule that blocks non-tunnel egress while the VPN is up. Some VPN clients ship a "lockdown mode" that does this for you — check yours. - All platforms — the real answer: assume the LAN is hostile. If you're at a coffee shop, hotel, or airport, the only safe VPN is one whose client runs inside an isolated network namespace. Anything else is trust in the DHCP server, and that's exactly the trust TunnelVision exploits.
Why this matters more for homelab users than the enterprise framing suggests
Enterprise threat models tend to dismiss TunnelVision as "needs LAN adjacency, so it's a hostile-Wi-Fi problem". That framing undersells the homelab case. The whole reason most homelab users run a VPN back to their lab is to reach it from networks they explicitly don't control — the coffee shop, the hotel, the conference, the in-laws' router. That is precisely the threat model TunnelVision was built for. The premise of "I'm tunnelling back to my stuff from a network I don't trust" is exactly what the attack inverts: the network you don't trust gets to decide which traffic actually enters your tunnel.
For wired-only access to your homelab from a network you control, TunnelVision is mostly a theoretical worry. For the Tailscale-on-the-laptop case, it's worth a serious read of your client's lockdown options. See also before you expose a service to the web for the other half of the homelab perimeter conversation.
What Noxen does about this
Noxen inventories installed VPN-client packages (wireguard-tools, openvpn,
tailscale, strongswan, …) on every host you've enrolled — see
agentless SSH host inventory for how that works — and
surfaces the CVE-2024-3661 record against hosts running them.
The honest limit: this is not a "Noxen tells you to upgrade wireguard-tools to version X" finding. There is no fixed version. The remediation is configuration on the client host (namespacing, routing policy, or "trust the LAN you're on"), not a package upgrade. Noxen flags the exposure so it shows up in your fleet review; the fix lives in the deployment shape. That same gap is why the patching gap is wider for protocol-class issues than it is for "CVE in package, fix in package" cases.
Authoritative sources
- NVD entry for CVE-2024-3661
- cve.org record
- Leviathan Security Group — TunnelVision disclosure
- RFC 3442 — DHCP Classless Static Route Option
See what Noxen does about CVEs like this → More on CVE management →