Summary
syncAgentsToDirectory in opencode-plugin/src/tools/sync-team.ts uses agent.name from the Fyso API response directly in path.join() to construct file paths (lines 104, 136). Since path.join resolves .. segments, a malicious agent name containing path traversal sequences (e.g. ../../.bashrc) would cause file writes and deletions outside the intended .claude/agents/ and .opencode/agents/ directories.
Evidence
- File:
opencode-plugin/src/tools/sync-team.ts, lines 104 and 136
- Code:
const filePath = join(claudeDir, \${agent.name}.md`)`
- Input source:
agent.name comes from the Fyso API via fetchTeamAgents (line 79-89), which reads _agent.name from the API response without validation.
- Amplifier: Line 105 does
if (existsSync(filePath)) await rm(filePath) before writing, so a crafted name could also delete existing files at the traversed path.
- Attack vector: Any user who can create agents in a Fyso team (or a compromised API response) could write arbitrary
.md files and delete existing files anywhere on the target user's filesystem when they run fyso-sync-team.
Acceptance criteria
- Agent names are sanitized before use in file path construction (reject or strip path separators,
.., and null bytes).
- The resolved file path is validated to remain within the expected output directory (
.claude/agents/ or .opencode/agents/).
- A test covers attempted path traversal via agent name (e.g.
../../etc/evil).
Suggested validation
- Create a test that calls
syncAgentsToDirectory with an agent whose name is ../../tmp/evil.
- Verify the function either throws an error or strips the traversal, and does NOT write to
/tmp/evil.md.
- Verify normal agent names (e.g.
architect, builder) still work correctly.
Pipeline
- Esta issue fue solicitada por un agente de mantenimiento programado.
- Entra sin labels para publicarse en triage; segun configuracion puede requerir aceptacion manual o autoaceptarse.
Summary
syncAgentsToDirectoryinopencode-plugin/src/tools/sync-team.tsusesagent.namefrom the Fyso API response directly inpath.join()to construct file paths (lines 104, 136). Sincepath.joinresolves..segments, a malicious agent name containing path traversal sequences (e.g.../../.bashrc) would cause file writes and deletions outside the intended.claude/agents/and.opencode/agents/directories.Evidence
opencode-plugin/src/tools/sync-team.ts, lines 104 and 136const filePath = join(claudeDir, \${agent.name}.md`)`agent.namecomes from the Fyso API viafetchTeamAgents(line 79-89), which reads_agent.namefrom the API response without validation.if (existsSync(filePath)) await rm(filePath)before writing, so a crafted name could also delete existing files at the traversed path..mdfiles and delete existing files anywhere on the target user's filesystem when they runfyso-sync-team.Acceptance criteria
.., and null bytes)..claude/agents/or.opencode/agents/).../../etc/evil).Suggested validation
syncAgentsToDirectorywith an agent whosenameis../../tmp/evil./tmp/evil.md.architect,builder) still work correctly.Pipeline