Describe the bug
toAbs (allowedpaths/sandbox.go) resolves relative paths via filepath.Join(cwd, path),
which lexically collapses .. segments before any filesystem/symlink resolution happens.
This diverges from POSIX/kernel path walking, which resolves .. against the resolved
location after following any preceding symlink component.
Reproduce
ln -s /tmp/outside /tmp/sandbox/link
cat link/../file # reads /tmp/sandbox/file, not /tmp/outside/file as GNU cat/the kernel would
Confirmed the same behavior on cat and rm; likely affects every builtin that resolves
a path through the sandbox (ls, echo redirection, etc.), since they all share toAbs/resolve().
For rm this doesn't create a cross-sandbox deletion risk in the case tested (it targets
the in-sandbox file, not the one outside), but the general divergence from real path
resolution semantics could matter for other commands or attack scenarios involving
symlinked intermediate components followed by ...
Fixing this properly means reworking path resolution in allowedpaths to walk ..
against the filesystem component-by-component (resolving symlinks as it goes) rather
than lexically collapsing the whole path up front — a cross-cutting change affecting
every builtin, not a single-command fix.
Originally raised via Codex review on #556: #556 (comment)
Describe the bug
toAbs(allowedpaths/sandbox.go) resolves relative paths viafilepath.Join(cwd, path),which lexically collapses
..segments before any filesystem/symlink resolution happens.This diverges from POSIX/kernel path walking, which resolves
..against the resolvedlocation after following any preceding symlink component.
Reproduce
ln -s /tmp/outside /tmp/sandbox/linkcat link/../file# reads /tmp/sandbox/file, not /tmp/outside/file as GNU cat/the kernel wouldConfirmed the same behavior on
catandrm; likely affects every builtin that resolvesa path through the sandbox (ls, echo redirection, etc.), since they all share
toAbs/resolve().For
rmthis doesn't create a cross-sandbox deletion risk in the case tested (it targetsthe in-sandbox file, not the one outside), but the general divergence from real path
resolution semantics could matter for other commands or attack scenarios involving
symlinked intermediate components followed by
...Fixing this properly means reworking path resolution in
allowedpathsto walk..against the filesystem component-by-component (resolving symlinks as it goes) rather
than lexically collapsing the whole path up front — a cross-cutting change affecting
every builtin, not a single-command fix.
Originally raised via Codex review on #556: #556 (comment)