You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Harden materialize: build the destination from a validated name, never git's path string
gitshow-research found a real hole in this module. `git ls-tree` can emit path strings
containing literal `../` segments -- git does not sanitise tree-entry names (a tree built
via mktree can name an entry `..`). The previous code derived the output path by slicing the
raw git path, so a crafted entry could aim the write, with only the safeJoin containment
check as a backstop.
The fix removes the class rather than guarding it: the skill name is now a validated capture
group (^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$ -- lowercase, no dots so no "..", no slashes),
and the destination is built from a FIXED TEMPLATE (pi/skills/<name>/SKILL.md), never from
git's reported string. classifyPiPath is the single choke point; selectEntries carries the
template-derived outRel. safeJoin still re-checks containment as defence in depth and now
splits the posix outRel into host segments (correct on Windows).
Tests add the traversal-name attack directly: `.pi/skills/../SKILL.md`,
`.pi/skills/../../etc/SKILL.md`, dotted and uppercase names all reject. The existing real-git
hostile-object tests (symlink-to-/etc/passwd, submodule) still pass. Files written 0o444 as
belt-and-braces behind the :ro mount.
This is the second security finding folded in from the git-extraction research; the
git-fetch-by-sha extraction method it validated (no clone, no checkout, no archive/tar --
archive+tar recreates live symlinks on disk) will be used by the worker's clone step.
0 commit comments