phantom-audio: Arbitrary File Write and Decode-Bomb DoS via Unconfined MCP Tool Paths
The Phantom audio MCP server let any AI agent write files to arbitrary locations on disk by passing an absolute output path, and had no cap on how large a decoded audio file could grow, making it poss
The problem
In phantom-audio <= 1.3.0, the MCP tool handlers accepted a caller-supplied output path with no directory confinement. When PHANTOM_OUTPUT_DIR was unset (the default), any client able to send a tool call could write or overwrite any file the process user owned.
Sensitive targets include ~/.zshrc, ~/.bash_profile, or a Reaper __startup.lua, all of which execute on the next shell or DAW launch.
Separately, the stem-separation and render code paths decoded input audio with no size or duration limit. A tiny, heavily compressed FLAC or OGG file can expand to gigabytes of raw PCM, exhausting memory. The analysis path already had guards, but separation and render did not, and the missing limits also widened exposure to decoder bugs such as libsndfile CVE-2026-37555.
Proof of concept
A working proof-of-concept for this issue in phantom-audio, with the exact payload below.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "separate_stems",
"arguments": {
"input_path": "/home/user/project/mix.flac",
"output_path": "/home/user/.zshrc"
}
}
}The root cause is the absence of a prefix check between the caller-supplied output_path and a trusted base directory (CWE-22) and unconstrained external control of that path (CWE-73). Before 1.3.1, the server passed the caller-supplied string directly to the file-write call without resolving symlinks or verifying that the resolved path fell inside PHANTOM_OUTPUT_DIR.
The patch confined every write to PHANTOM_OUTPUT_DIR (defaulting to ~/.phantom/output), resolved symlinks on both the configured directory and the final output path, and re-verified the resolved path before opening the file. The separation and render paths received matching decode guards: ffmpeg -max_alloc, -t, and -fs flags, plus an explicit duration/size check before decoding begins (CWE-400).
Public PoC not yet available. Payload derived from advisory description and patch behavior: the fix blocks any output_path whose os.path.realpath() does not share the PHANTOM_OUTPUT_DIR prefix, so the pre-patch attack was precisely any absolute path outside that directory.
The fix
Upgrade to phantom-audio 1.3.1. As an interim workaround on <= 1.3.0, set PHANTOM_OUTPUT_DIR and PHANTOM_AUDIO_DIR to dedicated, non-sensitive directories before starting the server. This does not fix the decode-bomb DoS, so upgrading is the only complete remediation.
Related research
- high · 7.5CVE-2026-49476CVE-2026-49476: soupsieve Memory Exhaustion via Unbounded Selector List
- high · 7.5CVE-2026-49477CVE-2026-49477: soupsieve Regular Expression Denial of Service (ReDoS)
- criticalCVE-2026-54760CVE-2026-54760: langroid SQLChatAgent pg_read_file Blocklist Bypass
- high · 7.8CVE-2026-53925CVE-2026-53925: Glances Arbitrary File Write via secure_popen Operator Injection in AMP Configuration