🐛 Bug Fixes
-
(atomic) Reject unsafe symlink targets during extraction - (f8642e1)
extractHandler validated entry names against path traversal but created
symlink entries with an unvalidated target. A crafted artifact could ship
a symlink whose target is absolute (/etc) or escapes via .., letting a
later entry written under it escape the release directory (the
symlink-based zip-slip variant).Add symlinkEscapes and reject symlink entries whose target is absolute or
resolves outside the release directory, before os.Symlink — matching the
existing entry-name traversal guard. Safe relative symlinks that resolve
inside the release directory are still extracted.Co-Authored-By:Claude noreply@anthropic.com
-
(deploy) Reject --interactive for remote (server) deploys - (ba5a0f3)
The M22 human+TTY guard runs before config load, so on a real TTY a
--interactivedeploy against a config withservers:passed the guard
and silently fell through to a client-mode SSH deploy — the flag was
accepted and ignored, because the remote agent runs in--output json
mode where per-step prompts are skipped.Reject
--interactivewith a Usage error (exit 1) after merge when the
config has servers, before the client-mode branch. Also correct spec 03,
which documented the guard's usage error as exit 2 (the code returns
cmderr.Usage = exit 1).IsTTY gains a SetIsTTY test seam (matching SetStatFile/SetInitWrite) so
the rejection can be unit-tested with a TTY forced on.Co-Authored-By:Claude noreply@anthropic.com
-
Bump forge to v0.17.1 - (d42f45a)
Inherits the updatecheck.Hinter.Print fix: the upgrade hint now
renders as multi-line and no longer prints a double trailing newline.go.mod/go.sum only.
📚 Documentation
-
(specs) Document archive extraction symlink safety - (896a2b7)
Spec 03 had no description of extraction safety. Document that step 6
treats the archive as untrusted: rejected entry names (absolute / ..),
rejected symlink targets (absolute, or relative escaping the release
dir), and that safe relative symlinks are extracted normally.Explain why absolute symlink targets are rejected unconditionally and
point to paths.shared as the sanctioned way to link a release file to a
fixed location outside the release.Co-Authored-By:Claude noreply@anthropic.com
Commit Statistics
- 4 commit(s) contributed to the release.
- 5 day(s) passed between the first and last commit.
- 4 commit(s) parsed as conventional.
- 0 linked issue(s) detected in commits.
- 9 day(s) passed between releases.