denoland/deno · critical

refusing symlink entry in laufey archive: {}

Error message

refusing symlink entry in laufey archive: {}

What it means

Thrown while extracting a LAUFEY Windows .zip when an entry is a symlink. Symlinks are refused categorically because a symlink-then-write pair inside one archive is the standard zip-slip-via-symlink escape (extract `foo -> ../../etc`, then write `foo/passwd`), and the LAUFEY Windows archives have no legitimate need for symlinks.

Source

Thrown at cli/tools/desktop.rs:2292

      };
      // Defence in depth — re-check the components ourselves.
      if rel_path.components().any(|c| {
        matches!(
          c,
          std::path::Component::ParentDir | std::path::Component::RootDir
        )
      }) {
        bail!(
          "refusing zip entry with traversal path: {}",
          rel_path.display()
        );
      }
      // Refuse symlinks: with prior entries already extracted, a
      // symlink-then-write pair is the standard zip-slip-via-symlink
      // escape, and LAUFEY Windows archives have no legitimate need for
      // them.
      if entry.is_symlink() {
        bail!(
          "refusing symlink entry in laufey archive: {}",
          rel_path.display()
        );
      }
      let dest_path = dest.join(&rel_path);
      if entry.is_dir() {
        std::fs::create_dir_all(&dest_path)?;
        continue;
      }
      if let Some(parent) = dest_path.parent() {
        std::fs::create_dir_all(parent)?;
      }
      let mut out = std::fs::File::create(&dest_path)?;
      std::io::copy(&mut entry, &mut out)?;
      #[cfg(unix)]
      {
        use std::os::unix::fs::PermissionsExt;
        // Mask to 0o755 / 0o644 — same policy as the tar branch.

View on GitHub (pinned to f7822238ca)

Solutions

  1. Do not extract with alternative tools that permit symlinks; keep the archive quarantined.
  2. Confirm the entry: `unzip -l` / `zipinfo` shows link entries and their targets.
  3. Clear the cache and retry once; if it reproduces, report to the deno/laufey maintainers.
Defensive patterns

Strategy: try-catch

Try / catch

# Security abort; do not extract symlinks manually
if deno desktop main.ts 2>&1 | grep -q "refusing symlink entry in laufey archive"; then
  echo "SECURITY: symlink in runtime zip — report upstream" >&2; exit 2
fi

Prevention

When it happens

Trigger: A zip containing a symlink entry (unix mode bits with S_IFLNK, or Windows symlink attributes) followed by a file that writes through it; a repackaged upstream archive that accidentally included symlinks from a Unix build.

Common situations: Not reachable via normal releases (checksum-gated); indicates a crafted archive, a compromised/mis-packaged release, or local cache corruption.

Related errors


AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20). Data as JSON: /api/errors/e3c6278d594b6e8c. Report an issue: GitHub.