Skip to content
← All articles

Phantom v1.3.1: Locking Down File Access

FadeLabs Team
FadeLabs Team -

v1.3.1 is a security release. Same 19 tools, no new features, nothing to demo.

Phantom runs on your machine with access to your audio files, and it takes file paths from an AI assistant. That combination deserves more care than we’d given it, so we ran an audit and fixed what it found.

Output confinement is on by default

The big one. Previously PHANTOM_OUTPUT_DIR was optional, and with it unset Phantom would write wherever it was told. Any tool that writes a file — fix_audio, apply_processing, separate_stems, match_to_reference, phantom render — could be pointed anywhere your user account could reach.

Now there’s always a sandbox. Unset, it defaults to ~/.phantom/output and gets created on demand. Set it, and writes are confined to that directory instead. Either way, a path outside the sandbox is rejected rather than honoured.

This is a behaviour change. If you had a workflow writing output next to your source files, it will now land in ~/.phantom/output unless you point PHANTOM_OUTPUT_DIR where you want it.

Confine first, then derive

Related, and subtler. When a tool builds a default output name from the input — vocals.wav becoming vocals_fixed.wav — the old code derived the path first and validated it second. That ordering meant a carefully shaped input path could produce a default output that landed outside the sandbox.

The order is reversed now: resolve the confined directory, then build the name inside it. Output reservation is atomic too, so two runs can’t race for the same filename.

Decode bombs

A small file can decode into an enormous array. A few hundred kilobytes of compressed audio can become gigabytes in memory, which is a cheap way to take down the process.

The separation and render paths now cap decoded size before committing to the work rather than finding out afterward.

load_audio validated a path and then reopened it to read. Between those two steps the file could be swapped for a symlink pointing somewhere else — a time-of-check to time-of-use race.

It now opens the validated path once and reads every byte through that same descriptor, so there’s no window to swap anything.

Dependencies

We upgraded to fastmcp >= 3.2, which cleared the outstanding Dependabot alerts, audited the rest of the tree against six advisories, and wired pip-audit into CI so the next one gets caught automatically instead of whenever someone thinks to look.

Updating

uv tool install "phantom-audio[all]" --python 3.13 --force

Worth doing even though there’s nothing new to play with. If you were relying on output landing somewhere specific, set PHANTOM_OUTPUT_DIR before you run anything.

← All articles