What happened
The AgentVCR record/replay component concatenates a caller-supplied cassette name with a .json suffix using path.join() and immediately reads/writes that path without checking the result stays under cassettePath. Because Node's path.join normalizes embedded '..' segments, a traversal name escapes the base directory. The demonstrated read primitive and the write primitive are bounded to JSON files the process can access, but in a multi-agent testing/orchestration deployment cassette names often come from untrusted sources, making an agent's recorded/saved state an arbitrary-JSON read/write channel.
Why it matters
Agent record/replay is a common way to make agent behaviour deterministic and inspectable; if the cassette name is untrusted, the same mechanism becomes an arbitrary JSON file read/write primitive inside an AI agent orchestration console, enabling config/policy tampering and credential or state disclosure from within the agent's own runtime.
Attack vector
AgentVCR builds cassette file paths via path.join(cassettePath, name + '.json') with no normalization-and-containment check. An attacker controlling the name argument supplies relative traversal sequences (../../...) so load() reads arbitrary .json files and returns their contents, and save() writes or overwrites arbitrary .json files — enough to forge the orchestrator's own policy files (a crafted trust-level entry was shown to grant an agent an authorization the operator had placed below the denial threshold) and to invalidate the tokens held by legitimate agents.
Affected systems
network-ai npm package, AgentVCR (lib/agent-vcr.ts), 5.13.4 through 5.15.4; fixed in 5.15.5
Mitigation
Upgrade to network-ai >= 5.15.5 (the advisory's confirmed fix range is before 5.15.5); stop deriving cassette names from untrusted input or validate/contain them within the configured cassette directory.