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
- Treat the file as malicious/untrusted and reject it
- Inspect archive listing (unrar l) to find the offending entry name
- Regenerate the archive with relative paths rooted in one directory
- Sanitize header names at creation time (strip drive letters, leading '/', '..')
- 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
- Pre-list archive contents (unrar lb) and validate entry paths before extraction
- Reject archives with absolute paths or '..' components
- Extract only into a dedicated, sandboxed directory
- Never trust archives from unverified uploaders
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
- illegal file path:
- disk quota exceeded
- rar command not found, please install it first
- source file/directory does not exist: %s
- rar compression failed: %s - %s
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/e5733b8f4e97e77e.
Report an issue: GitHub.