{"record":{"id":"9e8603fac8846115","repo":"denoland/deno","slug":"refusing-tar-entry-with-traversal-path","errorCode":null,"errorMessage":"refusing tar entry with traversal path: {}","messagePattern":"refusing tar entry with traversal path: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cli/tools/desktop.rs","lineNumber":2228,"sourceCode":"    let mut archive = tar::Archive::new(decoder);\n    // Strip mode bits from archive entries: a tampered archive could\n    // otherwise ship setuid/setgid binaries into the deno cache. Files keep\n    // the umask-applied default; we re-add execute bits below for entries\n    // that need them.\n    archive.set_preserve_permissions(false);\n    for entry in archive.entries()? {\n      let mut entry = entry?;\n      let entry_path = entry.path()?.into_owned();\n      // Defence in depth — pre-check `..` / root before handing to\n      // `unpack_in`, since we want a hard error rather than the silent\n      // skip that `unpack_in` does for a rejected entry.\n      if entry_path.components().any(|c| {\n        matches!(\n          c,\n          std::path::Component::ParentDir | std::path::Component::RootDir\n        )\n      }) {\n        bail!(\n          \"refusing tar entry with traversal path: {}\",\n          entry_path.display()\n        );\n      }\n      // `unpack_in` (vs. `unpack(absolute_path)`) makes tar enforce its\n      // symlink + hardlink target containment too: a tar with entry A as\n      // symlink `foo -> ../../etc` followed by entry B writing\n      // `foo/passwd` would otherwise escape `dest`.\n      if !entry.unpack_in(dest)? {\n        bail!(\n          \"refusing tar entry that would unpack outside dest: {}\",\n          entry_path.display()\n        );\n      }\n      #[cfg(unix)]\n      {\n        use std::os::unix::fs::PermissionsExt;\n        let dest_path = dest.join(&entry_path);","sourceCodeStart":2210,"sourceCodeEnd":2246,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L2210-L2246","documentation":"Thrown while extracting the downloaded LAUFEY runtime tar archive: an entry's path contains a `..` (ParentDir) or root (RootDir) component, a classic path-traversal (tar-slip) attempt. This is a deliberate hard error — the underlying `unpack_in` would silently SKIP such entries, so the code pre-checks and refuses the whole archive instead. Since the archive passed the SHA-256 check before extraction, this indicates a malicious or corrupted UPSTREAM release, not a network issue.","triggerScenarios":"A crafted laufey release tarball containing entries like `../../etc/passwd` or `/etc/launcher`; a corrupted (bit-rotted) cache producing garbage paths; an upstream packaging bug that emitted absolute paths in the tar.","commonSituations":"Almost never in normal use — the checksum gate means you see this only if the pinned release itself contains such entries (compromised or mis-built release) or the local cache was corrupted after verification.","solutions":["Do NOT bypass the check or extract the archive manually — treat it as hostile until proven otherwise.","Inspect the archive safely: `tar -tvf <archive>` and look for absolute paths or `..` segments in the listing.","Clear the LAUFEY cache and re-download; if the mismatch reproduces, report it immediately to the deno/laufey maintainers with the archive name and URL."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"# Never bypass; surface as a security failure\nif deno desktop main.ts 2>&1 | tee /tmp/d.log && grep -q \"refusing tar entry\" /tmp/d.log; then\n  echo \"SECURITY: malicious/corrupt runtime archive — report upstream\" >&2; exit 2\nfi","preventionTips":["Keep the LAUFEY cache read-only for untrusted users to avoid post-verification tampering.","Pin to official Deno releases so archive pins and extractor checks stay in sync.","Treat any traversal hit as an upstream incident: report the archive name and URL."],"tags":["desktop","laufey","tar","path-traversal","zip-slip","security"],"backgroundTag":"zip-slip-path-traversal","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T04:17:50.494Z"}