Skip to content

security: alias path traversal in CommandRegistrar.register_commands() for flat agents #2229

Description

@mbachorik

Summary

Free-form aliases (permitted since #2125 / 4deb90f) can contain path separators that escape the agent commands directory when registered by flat-file agents (claude, gemini, copilot, etc.).

Root cause

`CommandRegistrar._compute_output_name()` returns the alias name unchanged for non-SKILL.md agents:

```python
if agent_config["extension"] != "/SKILL.md":
return cmd_name # alias returned as-is
```

A manifest alias like `../foo` produces:

```
commands_dir / "../foo.md" → escapes commands_dir
```

`alias_file.parent.mkdir(parents=True, exist_ok=True)` will even create the parent directories.

Not affected

SKILL.md agents (codex, kimi) are safe — `_compute_output_name` replaces `.` with `-` and prepends `speckit-`, neutralising traversal sequences.

Suggested fix

Validate alias strings against a safe identifier pattern before writing, or resolve `alias_file` and assert it stays within `commands_dir` before writing.

Discovery

Identified during review of PR #2027.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions