alibaba/spring-ai-alibaba · warning · SecurityException

非法路径访问尝试: ${path}

Error message

非法路径访问尝试: ${path}

What it means

During Studio knowledge retrieval code generation, each document's relative path is resolved against studioStoragePath and normalized; if the resolved path escapes the storage root (classic ../ traversal), a SecurityException('非法路径访问尝试: <path>') is thrown. This is a deliberate path-traversal guard protecting files outside the allowed document directory.

Source

Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/builder/generator/service/generator/workflow/sections/KnowledgeRetrievalNodeSection.java:102

				})
				.flatMap(List::stream)
				.filter(Document::getEnabled)
				.filter(d -> StringUtils.hasText(d.getPath()))
				.map(document -> {
					// 文件类型
					String contentType = document.getMetadata().getContentType();
					// 存储形式
					DocumentType documentType = document.getType();
					// 存储路径
					String path = switch (documentType) {
						case FILE -> {
							{
								Path p = Path.of(studioStoragePath);
								Path resolvedPath = p.resolve(document.getPath()).normalize();

								// 安全检查:确保解析后的路径仍在允许的目录范围内
								if (!resolvedPath.startsWith(p.normalize())) {
									throw new SecurityException("非法路径访问尝试: " + document.getPath());
								}

								yield resolvedPath.toAbsolutePath().toString();
							}
						}
						case URL -> {
							// 对URL路径进行基本验证
							String urlPath = document.getPath();
							if (urlPath == null || urlPath.trim().isEmpty()) {
								throw new IllegalArgumentException("URL路径不能为空");
							}
							yield urlPath;
						}
						default ->
							throw new UnsupportedOperationException("unsupported document type: " + documentType);
					};
					String fileName = document.getName();
					// 构造文件记录

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Fix the document.getPath() value in the knowledge base record so it is a plain relative path under the storage root.
  2. Re-import the workflow from a trusted source; sanitize imported document paths (strip leading '/', '..' segments).
  3. Verify studioStoragePath is the intended root — a wrong root can make legitimate relative paths appear to escape.

Example fix

// before
document.path = "../../etc/passwd"
// after
document.path = "docs/manual.pdf"  // relative, within studioStoragePath
Defensive patterns

Strategy: validation

Validate before calling

Path root = Path.of(studioStoragePath).normalize();
Path resolved = root.resolve(doc.getPath()).normalize();
if (!resolved.startsWith(root)) throw new SecurityException("Blocked path traversal: " + doc.getPath());

Type guard

boolean isInsideStorage(Path root, String relative) { return root.resolve(relative).normalize().startsWith(root.normalize()); }

Try / catch

try { generator.generate(spec); } catch (SecurityException e) { log.warn("Rejected unsafe document path: {}", e.getMessage()); /* skip or fix the document record */ }

Prevention

When it happens

Trigger: render() on a STUDIO knowledge retrieval node where a ResourceFile's path contains '..' or absolute components such that p.resolve(path).normalize() no longer starts with the normalized storage root.

Common situations: A malicious or corrupted imported workflow references document paths like '../../etc/passwd'; database rows for document paths were edited by hand; symlinks/absolute paths in stored document metadata.

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


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/d58040adb9b3f05d. Report an issue: GitHub.