Summary
registerSurface(name) in src/applescript-transport.ts writes \${SURFACES_DIR}/\${agentName}.json with no basename or character validation. A name containing ../ can write/remove .json files outside ~/.swarm/surfaces.
Evidence
src/applescript-transport.ts:119 — path.join(SURFACES_DIR, \${agentName}.json`)` on unvalidated input.
- Entry path:
swarm join <name> (headless) → registerSurface(name) via src/index.ts:89.
Impact
Arbitrary-path file write/overwrite scoped to files ending in .json. In combination with the filename being partially operator-controlled, enables clobbering of config or state files the user has write access to.
Fix sketch
Validate name at registration (same ^[A-Za-z0-9_-]{1,64}$ shared with issue #1), and defense-in-depth: assert the resolved path is still under SURFACES_DIR before writing.
Context
Surfaced by codex challenge during review of PR #1 (lazy-reap). Out of scope for that PR — filing here per Lead.
Summary
registerSurface(name)insrc/applescript-transport.tswrites\${SURFACES_DIR}/\${agentName}.jsonwith no basename or character validation. A name containing../can write/remove.jsonfiles outside~/.swarm/surfaces.Evidence
src/applescript-transport.ts:119—path.join(SURFACES_DIR, \${agentName}.json`)` on unvalidated input.swarm join <name>(headless) →registerSurface(name)viasrc/index.ts:89.Impact
Arbitrary-path file write/overwrite scoped to files ending in
.json. In combination with the filename being partially operator-controlled, enables clobbering of config or state files the user has write access to.Fix sketch
Validate name at registration (same
^[A-Za-z0-9_-]{1,64}$shared with issue #1), and defense-in-depth: assert the resolved path is still underSURFACES_DIRbefore writing.Context
Surfaced by codex challenge during review of PR #1 (lazy-reap). Out of scope for that PR — filing here per Lead.