{"record":{"id":"0e726806ceadf47d","repo":"Tencent/WeKnora","slug":"path-traversal-denied-path-is-outside-base-direct","errorCode":null,"errorMessage":"path traversal denied: path is outside base directory","messagePattern":"path traversal denied: path is outside base directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/utils/security.go","lineNumber":123,"sourceCode":"}\n\n// SafePathUnderBase 校验 filePath 是否落在 baseDir 下，防止路径遍历（如 ../../）。\n// 返回规范化的绝对路径；若路径逃逸出 baseDir 则返回错误。\nfunc SafePathUnderBase(baseDir, filePath string) (string, error) {\n\tif baseDir == \"\" || filePath == \"\" {\n\t\treturn \"\", fmt.Errorf(\"baseDir and filePath cannot be empty\")\n\t}\n\tabsBase, err := filepath.Abs(filepath.Clean(baseDir))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid base dir: %w\", err)\n\t}\n\tabsPath, err := filepath.Abs(filepath.Clean(filePath))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid file path: %w\", err)\n\t}\n\tsep := string(filepath.Separator)\n\tif absPath != absBase && !strings.HasPrefix(absPath, absBase+sep) {\n\t\treturn \"\", fmt.Errorf(\"path traversal denied: path is outside base directory\")\n\t}\n\treturn absPath, nil\n}\n\n// SafeFileName 校验并返回安全的“仅文件名”部分，防止路径遍历。\n// 仅保留最后一个路径成分，禁止 \"..\"、空名或仅含点，用于 SaveBytes 等场景。\nfunc SafeFileName(fileName string) (string, error) {\n\tif fileName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"fileName cannot be empty\")\n\t}\n\tbase := filepath.Base(filepath.Clean(fileName))\n\tif base == \"\" || base == \".\" || base == \"..\" {\n\t\treturn \"\", fmt.Errorf(\"invalid fileName: path traversal or empty name\")\n\t}\n\tif strings.Contains(base, \"..\") {\n\t\treturn \"\", fmt.Errorf(\"invalid fileName: contains path traversal\")\n\t}\n\tif len(base) > 255 {","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/utils/security.go#L105-L141","documentation":"Containment guard in SafePathUnderBase: after normalizing both paths, the file path is not equal to and does not lie under the base directory (prefix check with the path separator), so a path traversal such as ../.. was attempted and is denied.","triggerScenarios":"Thrown at internal/utils/security.go:123 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Keep requested paths inside baseDir; resolve user input against the base instead of concatenating raw input","Log the traversal attempt for security review","Reject rather than sanitize ambiguous paths"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}