xtekky/gpt4free · critical

unsafe path in archive: %s

Error message

unsafe path in archive: %s

What it means

First zip-slip guard in g4f-go/process.go: after stripping the detected top-level directory and cleaning the name, an entry that is '..' or starts with '../' aborts with 'unsafe path in archive'. Same traversal protection as the tar path, applied to the runtime's zip flavor (typically the Windows python embeddable zip).

Source

Thrown at g4f-go/process.go:86

		}
	}
	if top == "" || top == "." {
		return fmt.Errorf("archive has no top-level directory")
	}

	for _, f := range zr.File {
		rel := f.Name
		if top != "" {
			rel = strings.TrimPrefix(f.Name, top+"/")
			rel = strings.TrimPrefix(rel, top)
		}
		rel = strings.TrimPrefix(rel, "/")
		name := filepath.Clean(rel)
		if name == "." || name == "" {
			continue // skip the top dir itself
		}
		if name == ".." || strings.HasPrefix(name, ".."+string(os.PathSeparator)) {
			return fmt.Errorf("unsafe path in archive: %s", f.Name)
		}
		target := filepath.Join(dest, name)
		if !strings.HasPrefix(target, filepath.Clean(dest)+string(os.PathSeparator)) && target != filepath.Clean(dest) {
			return fmt.Errorf("unsafe path in archive: %s", f.Name)
		}
		if f.FileInfo().IsDir() {
			if err := os.MkdirAll(target, 0o755); err != nil {
				return err
			}
			continue
		}
		if err := os.MkdirAll(filepath.Dir(target), 0o755); err != nil {
			return err
		}
		rc, err := f.Open()
		if err != nil {
			return err
		}

View on GitHub (pinned to 973504e177)

Solutions

  1. Stop and discard the archive; list offending entries: unzip -l archive.zip and inspect for '..' paths
  2. Re-download from the official URL pinned in runtime.json
  3. Ensure the sha256 pin in the manifest is current so tampered zips fail verification earlier
  4. Never re-zip archives with path-junking tools that can produce traversal components

Example fix

# before
# unsafe path in archive: pyroot/../../evil.dll

# after
unzip -l runtime.zip | grep '\.\.'    # confirm offending entries
rm runtime.zip
curl -L -o runtime.zip "<official-pinned-url>"
Defensive patterns

Strategy: validation

Validate before calling

// scan zip entries for traversal names before extracting
func zipIsSafe(path string) (bool, error) {
    r, err := zip.OpenReader(path)
    if err != nil { return false, err }
    defer r.Close()
    for _, f := range r.File {
        name := filepath.Clean(f.Name)
        if name == ".." || strings.HasPrefix(name, "..") {
            return false, nil
        }
    }
    return true, nil
}

Try / catch

if err := extractZip(dest, r, size); err != nil && strings.Contains(err.Error(), "unsafe path in archive") {
    // quarantine archive + re-verify provenance; do not retry as-is
}

Prevention

When it happens

Trigger: A zip containing entries that reduce to parent directories after top-dir stripping, e.g. 'pyroot/../../evil.dll'. Occurs with crafted/malicious archives or broken repacking tools.

Common situations: Runtime zips fetched from unofficial mirrors; tampered downloads (the guard doing its job); archives built with nonstandard tools emitting '..' components.

Related errors


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/7d1bb98a3403a70b. Report an issue: GitHub.