What
readSpecArg (mcp-server/server.ts:673-707) canonicalizes args.spec_path, checks the canonical path is within an allowed root, and then calls readFile(args.spec_path) on the original string (semantic 4.3). A symlink component swapped between the check and the read makes the file read differ from the file checked.
Fix
Read the canonical path that was checked (readFile(resolvedSpecPath)); one line. Test: the existing containment tests plus one that swaps a symlink between check and read is timing-dependent — the one-line fix is enough on its own.
Found by the 2026-09-15 self-audit (full-with-deep-audit on this repository at a159d6c, v0.25.0 + #353, ollama-cloud/deepseek-v4.1-flash); confirmed by reading before filing. Report and finding id in self-audit/2026-09-15-v0.25.0-full-with-deep-audit/REVIEW.md.
🤖 Generated with Claude Code
What
readSpecArg(mcp-server/server.ts:673-707) canonicalizesargs.spec_path, checks the canonical path is within an allowed root, and then callsreadFile(args.spec_path)on the original string (semantic 4.3). A symlink component swapped between the check and the read makes the file read differ from the file checked.Fix
Read the canonical path that was checked (
readFile(resolvedSpecPath)); one line. Test: the existing containment tests plus one that swaps a symlink between check and read is timing-dependent — the one-line fix is enough on its own.Found by the 2026-09-15 self-audit (
full-with-deep-auditon this repository ata159d6c, v0.25.0 + #353,ollama-cloud/deepseek-v4.1-flash); confirmed by reading before filing. Report and finding id inself-audit/2026-09-15-v0.25.0-full-with-deep-audit/REVIEW.md.🤖 Generated with Claude Code