Billionmail/BillionMail · critical

illegal file path:

Error message

illegal file path: 

What it means

While decompressing a rar archive, Decompress checks each header's filename (resolved to an absolute path) is a prefix-match under the destination root. Entries escaping that root — absolute paths or '../' traversal — abort extraction with this error, defending against Zip-Slip style attacks via crafted rar files.

Source

Thrown at core/internal/service/compress/rar.go:110

		}

		// remove ../ from filename to prevent path traversal
		arcName := filepath.ToSlash(filepath.Clean(header.Name))
		if strings.Contains(arcName, "../") {
			arcName = strings.Replace(arcName, "../", "", -1)
		}

		filename := filepath.Join(dst, arcName)

		// get absolute path of the file
		filenameAbs, err := filepath.Abs(filename)
		if err != nil {
			return err
		}

		// check if the file is under the decompression target path
		if !strings.HasPrefix(filenameAbs, dstAbs) {
			return errors.New("illegal file path: " + filename)
		}

		// check if it's a directory
		// if it's a directory, create it and skip
		if header.IsDir {
			err = os.MkdirAll(filename, 0755)
			if err != nil {
				return err
			}
			continue
		}

		// create directory
		err = os.MkdirAll(filepath.Dir(filename), 0755)
		if err != nil {
			return err
		}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Treat the file as malicious/untrusted and reject it
  2. Inspect archive listing (unrar l) to find the offending entry name
  3. Regenerate the archive with relative paths rooted in one directory
  4. Sanitize header names at creation time (strip drive letters, leading '/', '..')
  5. Note Go stdlib rar support is read-only; ensure the reading library matches the archive version

Example fix

// before
name := filepath.ToSlash(header.Name) // "../../evil.sh"
// after
name := strings.TrimLeft(header.Name, "/\\")
name = path.Clean(name)
if strings.HasPrefix(name, "../") { skip }
hdr.Name = filepath.Join("root", name)
Defensive patterns

Strategy: validation

Validate before calling

func rarHasSafeEntries(src string) error {
	list, err := exec.Command("unrar", "lb", src).Output()
	if err != nil { return err }
	dstAbs, _ := filepath.Abs(dst)
	for _, line := range strings.Split(string(list), "\n") {
		name := strings.TrimSpace(line)
		if name == "" { continue }
		abs, _ := filepath.Abs(filepath.Join(dst, name))
		if !strings.HasPrefix(abs, dstAbs+string(os.PathSeparator)) { return fmt.Errorf("unsafe entry: %s", name) }
	}
	return nil
}

Try / catch

if err := r.Decompress(dst, src); err != nil && strings.HasPrefix(err.Error(), "illegal file path") {
	// reject/quarantine the rar file; surface the offending entry name
}

Prevention

When it happens

Trigger: Calling RarUnpacker.Decompress (or Unrar) on a .rar containing entries with absolute filenames or '../' components that resolve outside dst.

Common situations: Malicious uploaded archives; archives created from absolute paths on another machine; buggy archiver that wrote non-relative entry names.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/e5733b8f4e97e77e. Report an issue: GitHub.