jdx/mise · error
brew-cask: refusing to stage cask payload through a path out
Error message
brew-cask: refusing to stage cask payload through a path outside the caskroom: {} What it means
A security guard during cask payload staging: the computed destination (caskroom joined with the staged relative path) does not resolve to a location inside the caskroom, likely due to symlink traversal or '..' components. mise bails instead of writing outside the caskroom.
Source
Thrown at src/system/packages/brew/cask/mod.rs:3110
.iter()
.filter_map(|app| find_app(stage, &app.source))
.map(|source| file::desymlink_path(&source))
.collect();
for entry in std::fs::read_dir(stage)? {
let source = entry?.path();
if !path_starts_with_resolved_root(&source, stage) {
continue;
}
let resolved = file::desymlink_path(&source);
if app_sources.contains(&resolved) {
continue;
}
let Some(relative) = staged_relative_path(stage, &source) else {
continue;
};
let target = caskroom.join(&relative);
if !path_starts_with_resolved_root(&target, caskroom) {
bail!(
"brew-cask: refusing to stage cask payload through a path outside the caskroom: {}",
target.display()
);
}
if target.symlink_metadata().is_ok() {
continue;
}
if let Some(parent) = target.parent() {
file::create_dir_all(parent)?;
}
if source.is_dir() {
file::copy_dir_all_preserve_symlinks(&source, &target)?;
} else {
file::copy(&source, &target)?;
}
}
Ok(())
}View on GitHub (pinned to afd2eddd3a)
Solutions
- Remove any '..' components or symlink indirection from the staged payload paths
- Inspect the caskroom for pre-existing symlinks pointing outside it and delete them
- Re-extract the cask archive from a trusted source and retry the install
Example fix
// before relative = "../../etc/foo" // escapes caskroom // after relative = "scripts/foo" // stays under caskroom
Defensive patterns
Strategy: validation
Validate before calling
let target = caskroom.join(&relative);
if !target.starts_with(&caskroom) || relative.components().any(|c| c == Component::ParentDir) {
return Err("payload path escapes the caskroom");
} Prevention
- Reject any payload entry containing '..' at archive extraction time
- Avoid placing symlinks inside the caskroom that point outside it
- Verify stage and caskroom roots are real directories, not symlinked into other trees
When it happens
Trigger: Staging a cask payload file whose relative path escapes the caskroom via '..' components or a symlink inside the caskroom pointing elsewhere, detected by path_starts_with_resolved_root before any write.
Common situations: Crafted or corrupted cask archives containing path-traversal entries, a previously created symlink in the caskroom redirected at another directory, or a stage root itself being a symlink into a different tree.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- brew-cask: invalid {kind} '{value}'
- brew-cask: staged symlink path escaped extraction root: {}
- brew-cask: refusing generic artifact source outside the extr
- brew-cask: refusing to stage generic artifact through a path
- brew-cask: completion target '{}' must not contain '..'
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/77abecf29da5c6e3.
Report an issue: GitHub.