jdx/mise · critical
vfox plugin archive contains an unsafe path
Error message
vfox plugin archive contains an unsafe path
What it means
When validating a vfox plugin archive before extraction, mise checks every entry path for unsafe components. Any path component that is not Normal (e.g. `..`, absolute/root, prefix components), or a name containing backslashes/colons or a `.git`/state-file name, causes the archive to be rejected as containing an unsafe (path-traversal) path.
Source
Thrown at src/plugins/packslip.rs:225
pub(crate) fn validate_archive(path: &Path) -> Result<()> {
let reader = flate2::read::GzDecoder::new(std::fs::File::open(path)?);
let mut archive = jdx_tar::Archive::new(reader);
for entry in archive.entries()? {
let entry = entry?;
ensure!(
matches!(
entry.entry_type(),
jdx_tar::EntryType::File | jdx_tar::EntryType::Directory
),
"vfox plugin archive contains a link or special file"
);
let path = entry.path()?;
for component in path.components() {
if component == Component::CurDir {
continue;
}
let Component::Normal(name) = component else {
bail!("vfox plugin archive contains an unsafe path");
};
let name = name.to_string_lossy();
ensure!(
!name.contains(['\\', ':'])
&& !name.eq_ignore_ascii_case(".git")
&& !name.eq_ignore_ascii_case(STATE_FILE),
"vfox plugin archive contains a reserved or unsafe path"
);
}
}
Ok(())
}
pub(crate) fn validate_layout(path: &Path) -> Result<()> {
ensure!(
path.join("metadata.lua").is_file(),
"vfox plugin archive must contain metadata.lua at its root"
);View on GitHub (pinned to afd2eddd3a)
Solutions
- Obtain the plugin archive from the trusted upstream source / re-download it; treat this as a potentially malicious archive and don't extract it manually elsewhere.
- Repackage the archive correctly: build it with relative paths from the plugin root, excluding .git, using forward slashes and no `..` or drive-letter components.
- Report the offending plugin/archive to its maintainer if the unsafe paths appear in the official release.
Example fix
// before (repackaging includes traversal + .git) tar -czf plugin.tar.gz ../my-plugin/.git ../my-plugin // after cd my-plugin && tar -czf ../plugin.tar.gz --exclude=.git .
Defensive patterns
Strategy: try-catch
Validate before calling
import std::path::{Path, Component};
fn archive_entries_look_safe(entries: &[String]) -> bool {
entries.iter().all(|e| {
Path::new(e).components().all(|c| matches!(c, Component::Normal(n) if !n.to_string_lossy().contains(['\\',':']) && !n.eq_ignore_ascii_case(".git")))
})
} Try / catch
match install_vfox_plugin(archive) {
Err(e) if e.to_string().contains("unsafe path") => {
eprintln!("archive rejected as unsafe (possible path traversal); use a trusted source");
// do not extract manually
}
r => r,
} Prevention
- Only install vfox plugins from trusted, verified sources.
- Repackage archives with relative paths, forward slashes, and .git excluded.
- Verify archive integrity (checksums/signatures) before installing.
- Treat any 'unsafe path' rejection as a security signal and inspect the archive, not just retry.
When it happens
Trigger: Installing/updating a vfox plugin whose archive contains entries with `..` components, absolute paths, Windows drive/prefix components, or names with `\` or `:` or a top-level `.git`/state file — caught during validate_archive in packslip.rs.
Common situations: A maliciously crafted or compromised plugin archive attempting zip-slip traversal; archives built on Windows leaking drive-letter or backslash paths; archives that accidentally include their .git directory; corrupted archives with mangled entry names.
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
- vfox plugin archive contains a reserved or unsafe path
- content-level SLSA verification rejected unsafe archive path
- vfox plugin archive contains a link or special file
- [dotfiles]."{}": target is not a safe OCI path
- mise oci build does not support asdf/vfox plugins in v1 (the
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/061ccf2874da5b32.
Report an issue: GitHub.