{"record":{"id":"a8767cc276bfdf8a","repo":"denoland/deno","slug":"refusing-tar-entry-that-would-unpack-outside-dest","errorCode":null,"errorMessage":"refusing tar entry that would unpack outside dest: {}","messagePattern":"refusing tar entry that would unpack outside dest: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cli/tools/desktop.rs","lineNumber":2238,"sourceCode":"      // `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);\n        // `symlink_metadata` so we don't follow a just-extracted symlink\n        // and chmod its target.\n        if let Ok(meta) = std::fs::symlink_metadata(&dest_path)\n          && meta.file_type().is_file()\n        {\n          // Was the entry executable? If so, mask to 0o755; otherwise 0o644.\n          let mode = entry.header().mode().unwrap_or(0o644);\n          let safe = if mode & 0o111 != 0 { 0o755 } else { 0o644 };\n          let mut perms = meta.permissions();\n          perms.set_mode(safe);","sourceCodeStart":2220,"sourceCodeEnd":2256,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L2220-L2256","documentation":"Thrown while extracting the LAUFEY runtime tar when `unpack_in(dest)` returns false for an entry — meaning the tar crate itself judged that the entry (including symlink/hardlink targets, which `unpack_in` containment-checks) would land outside the destination. It is the second layer of defence after the explicit `..`/root pre-check, and like that check it produces a hard error instead of the silent skip `unpack_in` would otherwise do.","triggerScenarios":"A tar containing entry A as symlink `foo -> ../../elsewhere` followed by entry B writing through `foo/`; hardlink targets pointing to paths outside dest; any entry the tar crate's containment logic rejects as escaping the extraction root.","commonSituations":"Only with a crafted or badly damaged upstream release archive — the checksum verified beforehand, so a genuine hit means the pinned release is hostile or broken, or local cache corruption altered paths.","solutions":["Treat the archive as untrusted; do not extract it with other tools.","Inspect with `tar -tvf` and check symlink targets (`ls -l` on extracted copy is NOT safe — read the listing instead).","Clear the cache, retry once, and if it reproduces report the archive name/URL to the deno/laufey maintainers."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"# Non-negotiable abort — do not fall back to other extractors\nset +e; OUT=\"$(deno desktop main.ts 2>&1)\"; RC=$?; set -e\nif grep -q \"refusing tar entry that would unpack outside dest\" <<<\"$OUT\"; then\n  echo \"SECURITY: tar containment violated — quarantine cache and report\" >&2; exit 2\nfi\nexit $RC","preventionTips":["Do not extract runtime archives with tar(1) as a workaround — the guard exists because silent skips hide escapes.","Clear the cache and re-download once to rule out local corruption.","Report reproducible hits with the exact entry path from the message."],"tags":["desktop","laufey","tar","symlink","path-traversal","security"],"backgroundTag":"zip-slip-path-traversal","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T04:17:50.494Z"}