Dev.to Security 🔐 Cybersecurity 👁 0 📖 6 min read

Go 1.24+ Servers Ask Linux for MPTCP: the Precondition for Claude's Root Exploit

Book: System Design Pocket Guide: Fundamentals Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go My project: Hermes IDE | GitHub — an IDE for developers who

Go 1.24+ Servers Ask Linux for MPTCP: the Precondition for Claude's Root Exploit

If your Go service runs on Linux and its main module targets Go 1.24 or later, it asks the kernel for a multipath TCP (MPTCP) listener. Anthropic wrote on October 27 that Claude, "after initial prompting," built a remote root exploit for "Linux servers with a multipath TCP listener." Two days later the Go Security Team sent golang-announce a note on protecting Go programs against CVE-2026-98432 (archived on oss-security). Its message for Go developers: unless you told it not to, a Go 1.24+ server requests exactly that kind of listener.

The Go docs say that since Go 1.24 the multipathtcp setting "defaults to multipathtcp="2", thus enabled by default on listeners." You probably never chose that.

What changed since Anthropic's post

Anthropic's October 27 post described the bug as "a race condition-induced UAF bug in the kernel networking stack" and said it took the model's exploit "48 minutes to leak a kernel pointer and another five minutes to reach the shell command execution." The model is "an unreleased, internal research model," and Anthropic has not published the exploit.

The Go team's October 29 announcement tied the exploit's precondition to Go's default and listed mitigations. On October 30, Red Hat published RHSB-2026-016 and rated the flaw Critical for RHEL 8, 9 and 10 and OpenShift. It lists no fixed kernels yet and says Red Hat "is expediting the release of fixes."

The distributions have split. Debian has fixed kernels for bookworm and trixie. Ubuntu's tracker, last updated October 30, still lists the linux package as vulnerable on every release from 16.04 to 26.10, with work in progress on 22.04, 24.04, 26.04 and 26.10.

The CVE itself is older. Ubuntu lists it as published on October 15 with a CVSS 3 score of 9.8, and Debian's tracker describes IP options being freed while another CPU still reads them during the IPv4 TCP handshake.

Why a Go server meets the precondition

Go 1.21 added Multipath TCP, but only when an application asked for it. Go 1.24 changed the default to multipathtcp=2: MPTCP on for listeners, off for dialers. Every net.Listen("tcp", ...) and every http.ListenAndServe in a program whose main module declares go 1.24 or later (in go.mod or go.work) requests an MPTCP socket from the kernel, unless a godebug setting says otherwise. The toolchain version alone doesn't decide it. Per the GODEBUG docs, a newer toolchain building a module that still says go 1.23 keeps the old opt-in behavior.

Whether the kernel hands one back depends on the host. The kernel switch is net.mptcp.enabled. TuxCare, which sells KernelCare, a live kernel patching service, says Enterprise Linux 8, 9 and 10 ship with MPTCP disabled, so a Go service on a stock RHEL host falls back to plain TCP. Don't assume. Check each host:

# 1 means the kernel will create MPTCP sockets
sysctl net.mptcp.enabled

# listening MPTCP sockets and the process that owns each
sudo ss -Mlnp

If the second command lists your Go binaries, they meet the precondition Anthropic described.

The Go team is careful about what that means. Its announcement says the bug is not specific to MPTCP, and a Go maintainer said the same on the proposal issue. Per Debian's tracker, the root cause is a use-after-free in Linux's IPv4 TCP handling. Turning MPTCP off removes the one path that has been demonstrated. Nobody has said it is the only path.

Flat vector illustration of a two-lane road merging into a single open gate at the base of a server tower, one lane drawn in burnt orange
A Go 1.24+ server asks the kernel for MPTCP on its listeners. The kernel decides whether that lane is open.

Patch first. The Go switches are a stopgap

The Go team calls a patched kernel "the best fix." Debian's fixed builds are 6.12.113-1 for trixie and 6.1.190-1 for bookworm, per its tracker. A new kernel package only protects you after a reboot.

Until then, the announcement lists three ways to keep a Go program on plain TCP. The quickest needs no rebuild. Set it in the service's environment and restart:

GODEBUG=multipathtcp=0 ./server

If GODEBUG already holds settings, add this one with a comma. To bake it into the binary, put it in the main module's go.mod:

module example.com/server

go 1.24

godebug multipathtcp=0

Two catches from the GODEBUG docs. Only the main module's go.mod counts, so a library can't set this for you. And when you build inside a workspace, go.mod godebug lines are ignored and go.work is read instead.

The third switch is per listener. ListenConfig.SetMultipathTCP overrides the GODEBUG value for that one socket:

package main

import (
    "context"
    "log"
    "net"
    "net/http"
)

func main() {
    var lc net.ListenConfig
    lc.SetMultipathTCP(false) // plain TCP, whatever GODEBUG says

    ctx := context.Background()
    ln, err := lc.Listen(ctx, "tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    log.Fatal(http.Serve(ln, http.NotFoundHandler()))
}

The Go team's own verdict on all three is "a fragile mitigation." One forgotten MPTCP listener on the host, in any language, keeps the precondition alive, and the approach assumes every working exploit needs MPTCP. Red Hat's interim nftables rule, which drops inbound IPv4 TCP packets carrying IP options, has the same limit: Red Hat says it "cannot fully prevent it."

Flat vector illustration of three small toggle switches flipped off on a control panel, beside a much larger wrench tightening a bolt on a server chassis
GODEBUG covers a process, go.mod covers a binary, SetMultipathTCP covers one listener.

Should Go flip the default back?

A proposal to disable MPTCP by default was opened on October 29 and is still open. Maintainers disagree. One Go maintainer wrote that changing the default now would be "closing the barn door after the horse has left," and asked for a justification of the current default, noting Go seems unusual in having one. Another Go team member wrote: "I don't see any reason that a security issue should lead us to disable it." A Linux kernel MPTCP developer joined to argue for MPTCP's benefits, such as moving a connection between networks without dropping it, and to say listener-side MPTCP has no performance cost for plain TCP clients. The Go team's announcement calls a default change "premature" for now.

Some projects aren't waiting. The Lightning Network daemon lnd merged a change on October 30 that, in an lnd developer's words, "makes plain TCP the default for newly built lnd binaries." The same developer told operators that "Disabling MPTCP removes the prerequisite for the demonstrated exploit," and that they "should still install a patched kernel as soon as one is available."

What to do this week

  1. Run sudo ss -Mlnp on every Linux host that faces the internet. Note which processes hold MPTCP listeners.
  2. Check your distribution's tracker for a fixed kernel: Debian, Ubuntu, Red Hat. Install it and plan the reboot.
  3. Check the go line in each service's go.mod (or go.work). At go 1.24 or later, assume the service requests MPTCP unless a godebug setting turns it off.
  4. Where no fixed kernel exists yet, set GODEBUG=multipathtcp=0 on Go services and restart them. Add godebug multipathtcp=0 to go.mod if you don't use MPTCP on purpose.
  5. Look at which kernel completes the TCP handshake with outside clients. If a proxy terminates TCP in front of your Go service, that proxy's host is the one an outside peer reaches first, so patch it first.

If this was useful

The fix for this one is a kernel update and a reboot on every exposed host, and the hard part is doing that across a fleet without dropping traffic. Draining a node behind a load balancer, rolling it, and bringing it back is the kind of building block the System Design Pocket Guide: Fundamentals walks through. I also build Hermes IDE, a free, source-available desktop app (macOS, Windows, Linux) that runs Claude Code, Codex and other coding agents side by side, and each one can work on its own branch; star it on GitHub if that sounds useful.

System Design Pocket Guide: Fundamentals — Core Building Blocks for Scalable Systems

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.