alibaba/spring-ai-alibaba · warning · IllegalArgumentException
{fieldName} contains unsafe path segment: {segment}
Error message
{fieldName} contains unsafe path segment: {segment} What it means
FileSystemStore.validatePathSegment throws IllegalArgumentException('<field> contains unsafe path segment: <segment>') when a namespace or key would form an absolute path, span multiple path components, or equal '.'/'..'. This prevents path traversal and escaping the store root.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/store/stores/FileSystemStore.java:275
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
*/
private void ensureDirectoryExists(Path directory) throws IOException {
if (!Files.exists(directory)) {
Files.createDirectories(directory);
}
}
/**
* Get all items from file system.
* @return list of all items
*/
private List<StoreItem> getAllItems() {View on GitHub (pinned to f82da0b50f)
Solutions
- Restrict keys/namespaces to a safe charset regex like [A-Za-z0-9._-]+ (excluding '..')
- Replace path separators in incoming identifiers before storage
- Hash or UUID-encode untrusted identifiers instead of using them verbatim
- Catch IllegalArgumentException and reject the request as invalid input
Example fix
// before
String key = fileName; // may contain '/'
store.putItem(ns, key, value);
// after
String key = fileName.replaceAll("[^A-Za-z0-9._-]", "_");
if (key.equals("..") || key.equals(".")) key = "_";
store.putItem(ns, key, value); Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern SAFE = Pattern.compile("[A-Za-z0-9._-]+");
static boolean safe(String s) {
return s != null && SAFE.matcher(s).matches() && !s.equals("..") && !s.equals(".");
} Type guard
static boolean isPathSafe(String segment) {
return segment != null && !segment.contains("/") && !segment.contains("\\")
&& !segment.equals("..") && !segment.equals(".");
} Try / catch
try {
store.putItem(namespace, key, value);
} catch (IllegalArgumentException e) {
throw new BadRequestException("unsafe store key: " + e.getMessage());
} Prevention
- Treat namespace/key as untrusted input; whitelist characters
- Normalize separators before validation
- Log rejected segments to detect traversal attempts
When it happens
Trigger: Passing '/etc' or 'C:\\tmp' as a key, keys containing '/' or '\\' (multiple name components), or the literal segments '.' or '..' to any store operation.
Common situations: Using user-supplied filenames directly as keys; building keys like "dir/" + name; Windows vs Unix path separator surprises; attackers sending '../../secret' in API fields used as store keys.
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
- resolved path escapes root directory
- 非法路径访问尝试: ${path}
- Path traversal not allowed
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/c963825d157e6ecb.
Report an issue: GitHub.