# Escaping Linux Sandboxes via PipeWire (CVE-2026-5674)
This post walks through a sandbox escape from a Flatpak application via PipeWire. The vulnerability was discovered using my automated research pipeline with `Claude Code` and `Opus 4.6` back in April 2026. It was an exciting find, as this was the first bug I submitted to Red Hat.
**Claude Code was also excited finding this:**
Once discovered, I repro’d it manually to make sure it’s legit and then submitted it to Red Hat.
Let’s dive into it.
## PipeWire and PulseAudio
PipeWire is the default audio server on all modern Linux desktops now. Fedora, Ubuntu 24.04+, Debian 13,… It replaced PulseAudio but maintains backward compatibility.
Flatpak apps that need audio request `–socket=pulseaudio`.
At the core, a basic “Hello World” app with standard audio permission breaks out of the sandbox and gets full access to the user’s desktop, files, and credentials. The same attack applies to other Linux sandbox tech that connects a socket to PipeWire (e.g. Docker, etc..).
Let’s look at the vulns and exploit.
## The Vulnerabilities
The escape relies on three separate issues.
### 1. Authentication Cookie Is Never Validated
PulseAudio code contains cookie-based authentication. This is not a typical web cookie, just a name for an authentication token. It’s a 256-byte random value that lives at `~/.config/pulse/cookie`, and clients must present it to connect. PipeWire reads the cookie from the client, checks the length is 256 bytes, and then just… throws it away.
The relevant code in `pulse-server.c`:
“`
if (len != NATIVE_COOKIE_LENGTH) return -EINVAL; client->version = version; client->authenticated = true; // cookie value never compared
“`
The `cookie` variable is never referenced again after being read. Any 256 bytes of garbage will do. No comments in the code explain why the value is set to `true`. The original PulseAudio validates the cookie, however PipeWire does not.
I looked through the git history. This has been the behavior since the PulseAudio compatibility layer was first implemented.
### 2. Module Loading Is Enabled by Default
“`
#define DEFAULT_ALLOW_MODULE_LOADING “true”
“`
Any “authenticated” client can send `LOAD_MODULE` to load arbitrary PipeWire modules. A config option ( `pulse.allow-module-loading`) was added in May 2024, but it defaults to `true`.
Since authentication is broken, this means any process with socket access can load modules.
### 3. dlopen() With No Path Validation
When `module-ladspa-sink` is loaded, it takes a `plugin=` parameter and calls `dlopen()` on it directly:
“`
handle = dlopen(path, RTLD_NOW);
“`
There is no path validation or directory allowlist. So, we can load arbitrary libraries.
ELF constructors ( `__attribute__((constructor))`) run immediately on `dlopen()`.
This is the same pattern as CVE-2025-60616 in FFmpeg’s LADSPA loader.
Oh, and if you are wondering what `LADSPA` means, it stands for `Linux Audio Developer’s Simple Plugin API`. That’s something new I learned along the way.
## The Sandbox Escape
Flatpak’s `–socket=pulseaudio` grants access to the PulseAudio socket. Combined with any host-writable path (like `–filesystem=/tmp` in the demo), an app can escape the sandbox.
The exploit chain:
1. Write a malicious `.so` to a host-visible path (e.g. `/tmp`)
2. Connect to the PulseAudio socket
3. Send `PA_COMMAND_AUTH` with 256 bytes of garbage
4. Send `PA_COMMAND_LOAD_MODULE module-ladspa-sink plugin=/tmp/payload.so`
5. PipeWire, running **outside the sandbox**, calls `dlopen()` on the `.so`
6. The constructor executes in the user’s full context (outside the sandbox)
The app has no home directory access, no display access, no network. Yet after the exploit it can read your files, launch apps on your desktop, and access your credentials.
Note that PipeWire runs as a user-level service, not root. This is a sandbox escape, not privilege escalation. But the attacker goes from “sandboxed, can only play audio” to “full, unrestricted user context.”
## Proof of Concept
I built a Flatpak app called `net.wuzzi.Hello` that demonstrates this. It looks completely harmless:
“`
$ flatpak info –show-permissions net.wuzzi.Hello pulseaudio file access [/tmp/wuzzi:create]
“`
Two permissions. PulseAudio and write to temp directory. That’s it.
Running it:
“`
$ flatpak run net.wuzzi.Hello ================================= Hello World from Flatpak! This app only has PulseAudio permission. Nothing else. ================================= Hello, World! Enjoy your day! 🙂
“`
Looks innocent, but it also did this:
“`
$ cat ~/PIPEWIRE_RCE_PROOF.txt === FLATPAK SANDBOX ESCAPE === PipeWire RCE achieved from sandboxed Flatpak app This file was written to your HOME directory by PipeWire (outside the sandbox). The Flatpak app had NO home directory access.
“`
The app also launches gnome-calculator on the host desktop.
I also verified the negative case with `–socket=pulseaudio` removed, to make sure the exploit fails. Since this was AI discovered, and I have a healthy scepticism for AI output, I double-checked to not submit any slop.
## Real-World Scope
I was wondering how common pulseaudio access is in sandboxed apps, and quickly found one on Flathub:
– **Discord** has `–socket=pulseaudio` + `–filesystem=xdg-download`
Any Flatpak app with audio permission and any host-writable path is exploitable.
The same attack also works from Docker containers with the PulseAudio socket mounted, which is a standard setup for containerized audio.
## Mitigations
These were the mitigations and recommendations I provided. Any one of these breaks the chain:
1. **Validate the cookie.** Compare against `~/.config/pulse/cookie`, like PulseAudio does.
2. **Default** The option exists since May 2024. `allow-module-loading` to `false`.
3. **Restrict LADSPA plugin paths.** Only `dlopen()` from `/usr/lib/ladspa/` and `/usr/lib64/ladspa/`, not arbitrary paths.
To my understanding, locking down (3) is what was implemented to mitigate the issue.
## Disclosure Timeline
– **2026-04-03:** Vulnerability discovered using Claude Code and confirmed on PipeWire 1.0.5.
– **2026-04-04:** Reproduced on Debian 13 (aarch64)
– **2026-04-05:** Also confirmed POC on Ubuntu 24.04 (x86_64) and Debian 13 (aarch64)
– **2026-04-05:** Report submitted to Red Hat Product Security. A day or two later Red Hat assigned CVE-2026-5674 for later publication. CVSS Score High 8.8
– **2026-04-06:** Initial hardening patches landed in the PipeWire repository.
– **2026-07-28:** Red Hat Enterprise Linux 10 Patch Available: RHSA-2026:47083
Also, I got a shout out from Red Hat in the official CVE-2026-5674.
Cool.
## Conclusion
PipeWire’s PulseAudio compatibility never validates the authentication cookie. Module loading is enabled by default, and `dlopen()` loads whatever path you give it.
Together a sandboxed Flatpak app (or other sandbox with audio socket access), and you get full user-context code execution. A “Hello World” app with audio permission writes to your home directory and pops calculator on your desktop.
In short `–socket=pulseaudio` should mean “this app can play audio.”, but it actually meant “this app can execute arbitrary code as you.”
As far as I can tell the fix was for `dlopen()` to prevent loading libraries from arbitrary absolute paths.
Red Hat has released a fix. If you’re affected (e.g. PipeWire applies to most distros) update.
Cheers, Johann.
