{"record":{"id":"e5733b8f4e97e77e","repo":"Billionmail/BillionMail","slug":"illegal-file-path-e5733b","errorCode":null,"errorMessage":"illegal file path: ","messagePattern":"illegal file path: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/internal/service/compress/rar.go","lineNumber":110,"sourceCode":"\t\t}\n\n\t\t// remove ../ from filename to prevent path traversal\n\t\tarcName := filepath.ToSlash(filepath.Clean(header.Name))\n\t\tif strings.Contains(arcName, \"../\") {\n\t\t\tarcName = strings.Replace(arcName, \"../\", \"\", -1)\n\t\t}\n\n\t\tfilename := filepath.Join(dst, arcName)\n\n\t\t// get absolute path of the file\n\t\tfilenameAbs, err := filepath.Abs(filename)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// check if the file is under the decompression target path\n\t\tif !strings.HasPrefix(filenameAbs, dstAbs) {\n\t\t\treturn errors.New(\"illegal file path: \" + filename)\n\t\t}\n\n\t\t// check if it's a directory\n\t\t// if it's a directory, create it and skip\n\t\tif header.IsDir {\n\t\t\terr = os.MkdirAll(filename, 0755)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// create directory\n\t\terr = os.MkdirAll(filepath.Dir(filename), 0755)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/compress/rar.go#L92-L128","documentation":"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.","triggerScenarios":"Calling RarUnpacker.Decompress (or Unrar) on a .rar containing entries with absolute filenames or '../' components that resolve outside dst.","commonSituations":"Malicious uploaded archives; archives created from absolute paths on another machine; buggy archiver that wrote non-relative entry names.","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"],"exampleFix":"// before\nname := filepath.ToSlash(header.Name) // \"../../evil.sh\"\n// after\nname := strings.TrimLeft(header.Name, \"/\\\\\")\nname = path.Clean(name)\nif strings.HasPrefix(name, \"../\") { skip }\nhdr.Name = filepath.Join(\"root\", name)","handlingStrategy":"validation","validationCode":"func rarHasSafeEntries(src string) error {\n\tlist, err := exec.Command(\"unrar\", \"lb\", src).Output()\n\tif err != nil { return err }\n\tdstAbs, _ := filepath.Abs(dst)\n\tfor _, line := range strings.Split(string(list), \"\\n\") {\n\t\tname := strings.TrimSpace(line)\n\t\tif name == \"\" { continue }\n\t\tabs, _ := filepath.Abs(filepath.Join(dst, name))\n\t\tif !strings.HasPrefix(abs, dstAbs+string(os.PathSeparator)) { return fmt.Errorf(\"unsafe entry: %s\", name) }\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := r.Decompress(dst, src); err != nil && strings.HasPrefix(err.Error(), \"illegal file path\") {\n\t// reject/quarantine the rar file; surface the offending entry name\n}","preventionTips":["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"],"tags":["go","compression","rar","path-traversal","security"],"backgroundTag":"zip-slip-path-traversal","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}