{"record":{"id":"2ef73efdb8611a61","repo":"alibaba/spring-ai-alibaba","slug":"path-traversal-not-allowed","errorCode":null,"errorMessage":"Path traversal not allowed","messagePattern":"Path traversal not allowed","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/extension/file/LocalFilesystemBackend.java","lineNumber":105,"sourceCode":"\t}\n\n\tpublic LocalFilesystemBackend(String rootDir) {\n\t\tthis(rootDir, false, 10);\n\t}\n\n\t/**\n\t * Resolve a file path with security checks.\n\t *\n\t * When virtualMode=True, treat incoming paths as virtual absolute paths under\n\t * cwd, disallow traversal (.., ~) and ensure resolved path stays within root.\n\t * When virtualMode=False, preserve legacy behavior: absolute paths are allowed\n\t * as-is; relative paths resolve under cwd.\n\t */\n\tprivate Path resolvePath(String key) throws IllegalArgumentException {\n\t\tif (virtualMode) {\n\t\t\tString vpath = key.startsWith(\"/\") ? key : \"/\" + key;\n\t\t\tif (vpath.contains(\"..\") || vpath.startsWith(\"~\")) {\n\t\t\t\tthrow new IllegalArgumentException(\"Path traversal not allowed\");\n\t\t\t}\n\t\t\tPath full = cwd.resolve(vpath.substring(1)).normalize();\n\t\t\tif (!full.startsWith(cwd)) {\n\t\t\t\tthrow new IllegalArgumentException(\"Path:\" + full + \" outside root directory: \" + cwd);\n\t\t\t}\n\t\t\treturn full;\n\t\t}\n\n\t\tPath path = Paths.get(key);\n\t\tif (path.isAbsolute()) {\n\t\t\treturn path;\n\t\t}\n\t\treturn cwd.resolve(path).normalize();\n\t}\n\n\t@Override\n\tpublic List<FileInfo> lsInfo(String path) {\n\t\ttry {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/extension/file/LocalFilesystemBackend.java#L87-L123","documentation":"LocalFilesystemBackend.resolvePath() enforces sandboxing when operating in virtualMode: keys containing '..' or starting with '~' are rejected with IllegalArgumentException(\"Path traversal not allowed\"), before any filesystem access. This prevents reads/writes escaping the virtual root via relative segments.","triggerScenarios":"Calling dirPath/resolvedPath/searchPath/grepRaw (and thus resolvePath) with keys like \"../etc/passwd\", \"a/../../b\", or \"~/notes.txt\" while virtualMode is enabled.","commonSituations":"LLM/tool-generated file paths that include .. segments; user-supplied paths concatenated into keys; home-directory shorthand (~) assumed to work as in a shell.","solutions":["Remove '..' segments and '~' prefixes from the path before calling the backend.","Resolve the path against the intended root and pass the already-normalized absolute path.","If escaping the root is legitimately required, disable virtualMode and validate paths at the application layer.","Sanitize inputs with FilesystemInterceptor.validatePath() before forwarding to the backend."],"exampleFix":"// before\nbackend.listFiles(\"../outside/dir\"); // IllegalArgumentException\n\n// after\nString key = Paths.get(baseDir).resolve(userInput).normalize().toString();\nif (key.contains(\"..\")) throw new IllegalArgumentException(\"Invalid path\");\nbackend.listFiles(key);","handlingStrategy":"validation","validationCode":"if (key.contains(\"..\") || key.startsWith(\"~\")) {\n    throw new IllegalArgumentException(\"Path traversal not allowed: \" + key);\n}","typeGuard":"boolean isSafeKey(String key) {\n    String v = key.startsWith(\"/\") ? key : \"/\" + key;\n    return !v.contains(\"..\") && !v.startsWith(\"~\");\n}","tryCatchPattern":"try {\n    backend.readFile(key);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Path traversal\")) {\n        throw new SecurityException(\"Rejected unsafe path: \" + key, e);\n    }\n    throw e;\n}","preventionTips":["Sanitize all LLM/user-supplied paths before they reach the backend.","Do not use '~' shell shorthand in virtual-mode keys.","Resolve user input against a known root and normalize before use.","Log rejected traversal attempts for security auditing."],"tags":["security","path-traversal","filesystem"],"backgroundTag":"path-traversal-blocked","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}