{"record":{"id":"2b798687e4f9baa9","repo":"flipped-aurora/gin-vue-admin","slug":"s-2b7986","errorCode":null,"errorMessage":"路径越过根目录: %s","messagePattern":"路径越过根目录: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_task.go","lineNumber":312,"sourceCode":"\t}\n\tif isPathWithin(l.webRoot, target) {\n\t\treturn autoCodeTaskFrontend, nil\n\t}\n\treturn \"\", fmt.Errorf(\"自动代码目标不在服务端或前端目录内: %s\", target)\n}\n\nfunc pathWithin(root string, elems ...string) (string, error) {\n\troot, err := filepath.Abs(root)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tjoined := filepath.Join(append([]string{root}, elems...)...)\n\tjoined, err = filepath.Abs(joined)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif !isPathWithin(root, joined) {\n\t\treturn \"\", fmt.Errorf(\"路径越过根目录: %s\", joined)\n\t}\n\treturn filepath.Clean(joined), nil\n}\n\nfunc isPathWithin(root, target string) bool {\n\trel, err := filepath.Rel(filepath.Clean(root), filepath.Clean(target))\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn rel != \"..\" && !strings.HasPrefix(rel, \"..\"+string(filepath.Separator)) && !filepath.IsAbs(rel)\n}\n\nfunc hashAutoCodeTarget(target string) (string, bool, error) {\n\tcontent, err := os.ReadFile(target)\n\tif errors.Is(err, fs.ErrNotExist) {\n\t\treturn \"\", false, nil\n\t}\n\tif err != nil {","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_task.go#L294-L330","documentation":"pathWithin joins a root with user-supplied elements, absolutizes the result, and rejects it if it escapes the root (e.g. via \"..\" segments). This blocks path-traversal when building auto-code task paths from user input. newAutoCodeTaskLayout surfaces it verbatim.","triggerScenarios":"Calling newAutoCodeTaskLayout with elements containing ../ or absolute components such that filepath.Join(root, elems...) resolves above root, e.g. elems = [\"..\"] or a stored path captured with traversal characters.","commonSituations":"Malicious or buggy client input stored in an auto-code task record; joining a target file path recorded relative to a different root; copy-pasted Windows-style or absolute paths from another machine.","solutions":["Inspect the joined path in the error message; remove any '..' or absolute-path segments from the source data (DB record or request payload).","Re-create the auto-code task/record with a relative path valid under the expected root.","If paths come from user input, sanitize/reject them at the API layer before persisting.","Verify the root passed to pathWithin is itself absolute and correct (AutoCode.Root + Server/Web)."],"exampleFix":"// before: elems from user input contain traversal\nnewAutoCodeTaskLayout(root, \"../../etc/passwd\")\n// after: normalize and validate before calling\nrel := filepath.ToSlash(filepath.Clean(userPath))\nif strings.Contains(rel, \"..\") {\n    return errors.New(\"path must stay inside project\")\n}\nnewAutoCodeTaskLayout(root, rel)","handlingStrategy":"validation","validationCode":"func safeRelPath(p string) bool {\n    if filepath.IsAbs(p) || strings.Contains(p, \"..\") {\n        return false\n    }\n    return filepath.Clean(p) != \".\" && p != \"\"\n}","typeGuard":null,"tryCatchPattern":"layout, err := newAutoCodeTaskLayout(root, elems...)\nif err != nil {\n    if strings.Contains(err.Error(), \"路径越过根目录\") {\n        return fmt.Errorf(\"invalid stored path %q: %w\", strings.Join(elems, \"/\"), err)\n    }\n    return err\n}","preventionTips":["Store only cleaned relative paths in auto-code task records","Reject user input containing '..' or absolute paths at the API layer","Use filepath.Clean on any path before persisting it"],"tags":["autocode","path-traversal","security"],"backgroundTag":"path-traversal-detected","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}