{"record":{"id":"1f87e214f12fbf26","repo":"jeecgboot/JeecgBoot","slug":"error-1f87e2","errorCode":null,"errorMessage":"文件路径包含非法字符","messagePattern":"文件路径包含非法字符","errorType":"validation","errorClass":"JeecgBootException","httpStatus":null,"severity":"critical","filePath":"jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/llm/handler/EmbeddingHandler.java","lineNumber":978,"sourceCode":"            }\n            fileName = FilenameUtils.getName(fileName);\n            tempFilePath = tempFilePath + fileName;\n            FileDownloadUtils.download2DiskFromNet(filePath, tempFilePath);\n            filePath = tempFilePath;\n        } else {\n            //update-begin---author:wangshuai---date:2026-03-30---for:【issues/9424】CommandExecUtil 命令执行过程中存在疑似路径遍历漏洞/【issues/9425】EmbeddingHandler 知识库解析过程中疑似存在路径遍历漏洞---\n            // 1. 路径遍历检查：拒绝 .. 和 %2e 等绕过手段\n            SsrfFileTypeFilter.checkPathTraversal(filePath);\n            // 2. 标准化路径并校验是否在 uploadpath 范围内\n            Path root = Paths.get(uploadpath).toAbsolutePath().normalize();\n            //update-begin---author:wangshuai ---date:2026-04-13  for：zip文件 filePath 以 \\ 或 / 开头，在Windows下被Path.resolve当成驱动器根路径导致误判路径遍历，先剥掉前导分隔符-----------\n            // 去除前导分隔符，保证作为相对路径 resolve 到 uploadpath 之下\n            String relativePath = filePath.replaceAll(\"^[\\\\\\\\/]+\", \"\");\n            Path target = root.resolve(relativePath).toAbsolutePath().normalize();\n            //update-end---author:wangshuai ---date:2026-04-13  for：zip文件 filePath 以 \\ 或 / 开头，在Windows下被Path.resolve当成驱动器根路径导致误判路径遍历，先剥掉前导分隔符-----------\n            if (!target.startsWith(root)) {\n                log.error(\"检测到路径遍历攻击! filePath: {}, 解析后: {}\", filePath, target);\n                throw new JeecgBootException(\"文件路径包含非法字符\");\n            }\n            filePath = target.toString();\n            //update-end---author:wangshuai---date:2026-03-30---for:【issues/9424】CommandExecUtil 命令执行过程中存在疑似路径遍历漏洞/【issues/9425】EmbeddingHandler 知识库解析过程中疑似存在路径遍历漏洞---\n        }\n        return filePath;\n    }\n\n\n}\n","sourceCodeStart":960,"sourceCodeEnd":988,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/llm/handler/EmbeddingHandler.java#L960-L988","documentation":"Thrown by EmbeddingHandler.ensureFile() when a resolved file path escapes the upload directory after normalization. The method first calls SsrfFileTypeFilter.checkPathTraversal() to reject '..' and '%2e' patterns, then resolves the relative path against the upload root and checks that the normalized result still starts with the upload root. This is a path traversal / directory traversal security guard (issues #9424, #9425).","triggerScenarios":"A filePath containing '../' sequences (after any leading separators are stripped) that, when resolved against the upload root, points outside the upload directory. Also triggered by crafted paths using URL encoding or OS-specific separators that bypass the initial checkPathTraversal but resolve outside root.","commonSituations":"Malicious or corrupted filePath in document metadata pointing to system files; a zip extraction entry with a relative path that escaped the target dir and was stored as the filePath; a testing/debugging scenario with an absolute path from another drive or root.","solutions":["Ensure the filePath in document metadata is always a relative path under the upload directory.","Do not allow user-controllable input to set the filePath metadata field directly.","If the error persists with legitimate files, check that uploadpath is correctly configured and the file actually resides beneath it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure filePath is relative and within upload directory before processing\nString relativePath = filePath.replaceAll(\"^[\\\\\\\\/]+\", \"\");\nPath root = Paths.get(uploadpath).toAbsolutePath().normalize();\nPath target = root.resolve(relativePath).toAbsolutePath().normalize();\nif (!target.startsWith(root)) {\n    throw new JeecgBootException(\"文件路径非法\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    filePath = ensureFile(filePath);\n} catch (JeecgBootException e) {\n    if (e.getMessage().contains(\"文件路径包含非法字符\")) {\n        log.error(\"Path traversal attempt detected for filePath\");\n        throw new JeecgBootException(\"文件路径不合法，请检查文件配置\");\n    }\n    throw e;\n}","preventionTips":["Never allow user input to directly set the filePath metadata field.","Always store file paths as relative paths under the configured upload directory.","Run path-traversal checks on all file-path inputs at the API boundary, not just in low-level handlers.","Monitor and alert on path-traversal detection events as they may indicate attack attempts."],"tags":["security","path-traversal","directory-traversal","rag"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}