mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-08 01:43:55 +00:00
69ba0e6d21
* fix(stacks): harden stack file path containment against symlink escapes The legacy managed-stack methods enforced path containment lexically (path.resolve + startsWith), which does not follow symlinks. A stack directory under the compose root that is itself a symlink or junction could let a managed-file operation (write compose.yaml/.env, delete a stack, backup, restore, snapshot) follow the link and read, write, or delete a file of the same name outside the compose root. Add a realpath-based containment guard that walks up to the deepest existing path component, confirms its canonical location is inside the canonical compose root, and rejects both an out-of-tree resolution and a dangling symlink (which a write or mkdir would still follow). The guard runs at every legacy managed-stack sink, alongside the existing lexical barriers. A legitimately symlinked compose root is not a false positive because both sides are canonicalized through the same link, and the guard is a no-op for not-yet-created targets so stack creation and the flat-to-directory migration are unaffected. * fix(stacks): satisfy the path-injection sanitizer in the symlink containment guard assertRealWithinBase resolves a user-derived path and probes it with realpath/lstat to run the containment check, which static analysis flags as path injection because the probes lacked the inline barrier its sanitizer recognizes. Add the canonical path.resolve + startsWith barrier at the top of the helper, the same form every other sink in this file uses, and seed the realpath walk from the sanitized value. Behavior is unchanged: callers always pass an absolute, already-contained path, so the barrier is a no-op pre-check for them, and the realpath walk still catches the symlink and dangling-link escapes.