Summary
assertSkillSlug is enforced during skill creation, but most read/edit/delete skill routes accept raw :slug and use it to build filesystem paths. This leaves a path traversal attack surface (via crafted slugs) before canonical slug validation.
Affected code
src/utils/skill.ts
assertSkillSlug exists and is only used in createSkill(...)
getSkillPath(slug) + getSkillManifestPath(slug) join directly with provided slug
src/skills/index.ts
- routes like
GET /:slug, file routes, permissions update, delete, approve/reject use req.params.slug directly
Why this matters
Even if downstream code often fails safely, accepting unvalidated slugs in path construction creates avoidable filesystem traversal risk and makes security posture dependent on incidental checks.
Proposed fix
- Add a single helper to canonicalize/validate skill slug (reuse
assertSkillSlug).
- Apply it at the start of every
/:slug skill route (or in shared route middleware).
- Add tests for traversal payloads (e.g.
.., encoded separators, absolute-like inputs).
Acceptance criteria
- All skill routes reject invalid slugs with
400.
- Traversal/encoded traversal attempts cannot influence resolved filesystem path.
- Existing valid slugs continue to work.
Summary
assertSkillSlugis enforced during skill creation, but most read/edit/delete skill routes accept raw:slugand use it to build filesystem paths. This leaves a path traversal attack surface (via crafted slugs) before canonical slug validation.Affected code
src/utils/skill.tsassertSkillSlugexists and is only used increateSkill(...)getSkillPath(slug)+getSkillManifestPath(slug)join directly with provided slugsrc/skills/index.tsGET /:slug, file routes, permissions update, delete, approve/reject usereq.params.slugdirectlyWhy this matters
Even if downstream code often fails safely, accepting unvalidated slugs in path construction creates avoidable filesystem traversal risk and makes security posture dependent on incidental checks.
Proposed fix
assertSkillSlug)./:slugskill route (or in shared route middleware)..., encoded separators, absolute-like inputs).Acceptance criteria
400.