Billionmail/BillionMail · error
illegal file path:
Error message
illegal file path:
What it means
During Decompress, each entry's absolute target path is checked to ensure it resolves inside the destination directory (dstAbs). If a zip entry's filename escapes that directory — the classic Zip Slip path traversal — extraction is refused with this error naming the offending entry path.
Source
Thrown at core/internal/service/compress/zip.go:194
// remove ../ from filename
arcName := filepath.ToSlash(filepath.Clean(fz.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 fz.FileInfo().IsDir() {
// create directory
err = os.MkdirAll(filename, 0755)
if err != nil {
return err
}
continue
}
// create directory
err = os.MkdirAll(filepath.Dir(filename), 0755)
View on GitHub (pinned to fc36c76c05)
Solutions
- Verify the archive contents (unzip -l) and sanitize entry names before extraction; the error is correct — do not bypass it
- Reject or regenerate archives from untrusted sources; validate uploads before accepting them
- If a legitimate relative path is falsely flagged, check for absolute entry names or symlinks in the archive and normalize before packing
- Ensure the destination directory itself has no trailing-separator mismatch affecting strings.HasPrefix; prefer filepath.Rel-based checks if customizing
Example fix
// malicious entry name: "../../../../etc/cron.d/pwn" -> rejected // after sanitizing when repacking name: "etc/cron.d/pwn" -> extracts under dst
Defensive patterns
Strategy: validation
Validate before calling
func safeEntry(name string) bool {
cleaned := path.Clean(name)
return !strings.HasPrefix(cleaned, "../") && !path.IsAbs(cleaned)
} Type guard
func isInsideDst(entry, dst string) bool {
rel, err := filepath.Rel(dst, entry)
return err == nil && rel != ".." && !strings.HasPrefix(rel, ".."+string(filepath.Separator))
} Try / catch
err := z.Decompress(src, dst)
if err != nil && strings.Contains(err.Error(), "illegal file path") {
log.Warnf("zip-slip attempt blocked: %v", err)
return ErrUntrustedArchive
} Prevention
- Never extract untrusted archives without path validation
- Inspect archive entry names before extraction (zipinfo/unzip -l)
- Keep the library's prefix check intact — do not bypass it
- Quarantine archives that trigger this error
When it happens
Trigger: Extracting an archive whose entry names contain traversal segments like ../ or absolute paths (e.g. ../../etc/cron.d/evil, /etc/passwd) so that filepath.Abs(filename) is not a prefix-match under the destination.
Common situations: Processing user-uploaded zip files; extracting third-party archives from untrusted sources; malicious payloads crafted for path traversal to overwrite system files.
Related errors
- illegal file path:
- illegal file path:
- failed to create zip entry for %s: %v
- failed to close zip writer: %v
- configuration value contains illegal characters
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/eaf308bf99734679.
Report an issue: GitHub.