alibaba/spring-ai-alibaba · warning · IllegalArgumentException
resolved path escapes root directory
Error message
resolved path escapes root directory
What it means
FileSystemStore.createItemPath resolves namespace+key into a path under the store root and rejects the result if it does not start with the normalized absolute root path. This IllegalArgumentException guards against path traversal, e.g. a key containing '..' or an absolute path component that survives normalization.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/store/stores/FileSystemStore.java:264
}
}
/**
* Create item path from namespace and key.
* @param namespace namespace
* @param key key
* @return item path
*/
private Path createItemPath(List<String> namespace, String key) {
Path path = rootPath.toAbsolutePath().normalize();
for (String ns : namespace) {
validatePathSegment(ns, "namespace");
path = path.resolve(ns);
}
validatePathSegment(key, "key");
Path itemPath = path.resolve(key + ".json").normalize();
if (!itemPath.startsWith(rootPath.toAbsolutePath().normalize())) {
throw new IllegalArgumentException("resolved path escapes root directory");
}
return itemPath;
}
private void validatePathSegment(String segment, String fieldName) {
if (segment == null || segment.trim().isEmpty()) {
throw new IllegalArgumentException(fieldName + " cannot be null or empty");
}
Path candidate = Paths.get(segment);
if (candidate.isAbsolute() || candidate.getNameCount() != 1 || "..".equals(segment) || ".".equals(segment)) {
throw new IllegalArgumentException(fieldName + " contains unsafe path segment: " + segment);
}
}
/**
* Ensure directory exists.
* @param directory directory to create
*/View on GitHub (pinned to f82da0b50f)
Solutions
- Sanitize namespace/key to [A-Za-z0-9._-] before calling store APIs
- Reject keys containing path separators or '..' in your own validation layer
- Catch IllegalArgumentException and return a 400-style error to the caller
- Use fixed identifiers (UUIDs) instead of raw user strings as keys
Example fix
// before
store.putItem(List.of(userInputNs), userInputKey, value);
// after
if (!userInputKey.matches("[A-Za-z0-9._-]+")) {
throw new IllegalArgumentException("invalid key");
}
store.putItem(List.of(userInputNs), userInputKey, value); Defensive patterns
Strategy: validation
Validate before calling
static boolean safeSegment(String s) {
return s != null && s.matches("[A-Za-z0-9][A-Za-z0-9._-]*") && !s.equals("..") && !s.equals(".");
}
// call for every namespace element and the key before store APIs Try / catch
try {
store.getItem(namespace, key);
} catch (IllegalArgumentException e) {
throw new BadRequestException("invalid store key");
} Prevention
- Never pass raw user input as namespace/key
- Generate keys (UUID/hash) server-side
- Keep this guard even after library updates
When it happens
Trigger: Calling putItem/getItem/deleteItem/search with a namespace or key that normalizes outside the root (e.g. key '../escape', namespace containing '.' or '..' segments that slip past validatePathSegment on unusual platforms).
Common situations: Passing untrusted user input as namespace/key; keys built by string concatenation from request parameters; upstream validation removed leading '../' but not interior ones.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Path traversal not allowed
- Path traversal not allowed
- {fieldName} contains unsafe path segment: {segment}
- 非法路径访问尝试: ${path}
- Path traversal not allowed
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/979088fee0f40149.
Report an issue: GitHub.