News

Fix X11 Authorization Across Hosts with a One-Field Cookie Rewrite

When X11 clients fail with 'Authorization required' inside containers or over SSH, the culprit is a hostname-pinned cookie. Rewrite the family field to FamilyWild (0xffff) with a single sed command to make the cookie portable.

August 2, 2026· 3 min read
Fix X11 Authorization Across Hosts with a One-Field Cookie Rewrite

Running an X11 app from inside a container, a chroot, or over SSH often ends with the dreaded Authorization required, but no authorization protocol specified. The .Xauthority file is mounted right where the client expects it, yet X refuses the connection. The cause is subtle, and the fix is a one-line sed.

An .Xauthority file stores cookies keyed by a family and a hostname. When a client connects, it looks for the entry whose hostname matches the machine it believes it's on—not just any cookie. Inside a container or over an un-forwarded socket, the hostname differs from the one the cookie was minted for, so the client never offers the cookie and X falls back to 'no authorization protocol.'

You can inspect the keying with xauth list; the leading myhost/unix:0 pins the cookie to myhost.

FamilyWild to the rescue

X defines a wildcard family, FamilyWild, with numeric value 0xffff. A cookie in this family matches any hostname. Instead of making the client's hostname match the cookie, you rewrite the cookie to match every host.

Use xauth nlist to print entries in a numeric format where the first field is the 4-hex-digit family. Overwrite it with ffff and merge into a fresh file:

: > /tmp/portable.Xauthority && xauth nlist :0 | \
    sed 's/^..../ffff/' | xauth -f /tmp/portable.Xauthority nmerge -
# Replace :0 with your $DISPLAY value

The change is a single field

An .Xauthority entry is a packed binary record: a 2-byte family, then length-prefixed address, display number, auth name, and the cookie. Dumping the original file shows the family in the first two bytes—0100, i.e., FamilyLocal. After the rewrite, everything is byte-for-byte identical except those two bytes, now ffff. The address still spells myhost, but X no longer cares because family 0xffff matches unconditionally.

Bind-mount (or scp) /tmp/portable.Xauthority to the client, point XAUTHORITY at it, and the connection is accepted regardless of hostname mismatch.

What about xhost +?

xhost + disables host-based access control entirely, letting any client connect without a cookie. On a single-user machine that sounds harmless, but X has no isolation between clients: anyone who can reach the server can read keystrokes, grab window contents, and inject input. xhost + hands that to every local user and, if TCP is enabled, to the network. Even xhost +local: trusts every UID on the box.

The FamilyWild cookie keeps the door locked—the client must still present the secret—while removing only the hostname constraint. Reach for it instead of xhost +, and keep the cookie file at 0600.

One caveat

A FamilyWild cookie is deliberately less specific: anyone who can reach your X socket and read the file can talk to your display. Hand it only to environments that need it, and don't leave copies on shared machines.

This trick is part of a larger setup for forwarding X into unprivileged LXC containers, detailed in the author's Enhancing x11 Application Security with LXC.

The FamilyWild cookie keeps the door locked—a client still has to present the secret—while removing only the hostname constraint that was getting in the way.
Manul X Editorial