AlistGo/alist · error · ErrArchiveIllegalPath
ErrArchiveIllegalPath
ErrArchiveIllegalPath
Error message
archive entry has illegal path: %s
What it means
First rejection inside SecureJoin (internal/archive/tool/securepath.go): any archive entry name containing a NUL byte (\x00) is refused with ErrArchiveIllegalPath. NUL bytes can truncate path strings in downstream OS calls, a classic path-validation bypass, so they are rejected before any normalization.
Source
Thrown at internal/archive/tool/securepath.go:19
package tool
import (
"errors"
"fmt"
"os"
"path"
"path/filepath"
"strings"
)
// ErrArchiveIllegalPath indicates an archive entry path is unsafe for extraction.
var ErrArchiveIllegalPath = errors.New("archive entry has illegal path")
// SecureJoin returns a safe extraction path for an archive entry.
// It rejects absolute paths, traversal, Windows drive/UNC paths, and NUL bytes.
func SecureJoin(baseDir, entryName string) (string, error) {
if strings.Contains(entryName, "\x00") {
return "", fmt.Errorf("%w: %s", ErrArchiveIllegalPath, entryName)
}
normalized := strings.ReplaceAll(entryName, "\\", "/")
if strings.HasPrefix(normalized, "//") {
return "", fmt.Errorf("%w: %s", ErrArchiveIllegalPath, entryName)
}
cleaned := path.Clean(normalized)
if cleaned == "." || cleaned == ".." || strings.HasPrefix(cleaned, "../") {
return "", fmt.Errorf("%w: %s", ErrArchiveIllegalPath, entryName)
}
if strings.HasPrefix(cleaned, "/") {
return "", fmt.Errorf("%w: %s", ErrArchiveIllegalPath, entryName)
}
rel := filepath.FromSlash(cleaned)
if filepath.IsAbs(rel) || filepath.VolumeName(rel) != "" {
return "", fmt.Errorf("%w: %s", ErrArchiveIllegalPath, entryName)View on GitHub (pinned to 843d9dc814)
Solutions
- Treat the archive as untrusted; verify its source and hash before retrying
- List the archive with an external tool to identify the offending member and remove/repair it
- Re-create the archive from trusted content rather than bypassing the check
Defensive patterns
Strategy: validation
Validate before calling
// Go: reject entry names containing NUL before calling any extraction API
func hasNULName(names []string) bool {
for _, n := range names {
if strings.ContainsRune(n, 0) { return true }
}
return false
} Type guard
func isValidEntryName(name string) bool {
return !strings.Contains(name, "\x00")
} Try / catch
if err := tool.SecureJoin(outDir, name); err != nil {
if errors.Is(err, tool.ErrArchiveIllegalPath) {
// untrusted/corrupt archive: quarantine it; never strip NULs and retry
}
return err
} Prevention
- Validate member names (no NUL, no leading separators, no '..') when generating archives
- Scan untrusted archives with listing tools before extraction
- Treat NUL-in-name findings as tamper indicators
When it happens
Trigger: Extracting an archive whose member name embeds a NUL byte — typically a crafted/malicious archive (Zip-Slip variant) or a corrupted header producing embedded NULs in the decoded name.
Common situations: Deliberately malicious downloads; bit-corrupted archives; fuzz-generated files; archives produced by buggy packers that do not sanitize names.
Related errors
- archive entry has illegal path
- ErrArchiveIllegalPath
- total size of decompressed files exceeds the limit
- unknown archive format
- ErrArchiveIllegalPath
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/cfe907a7f03ace3b.
Report an issue: GitHub.