jeecgboot/JeecgBoot · error · JeecgBootException
非法文件路径,禁止访问上传目录之外的文件: {imageUrl}
Error message
非法文件路径,禁止访问上传目录之外的文件: {imageUrl} What it means
SECURITY control fixing CWE-22 (path traversal) in WordUtil.addImage(). When an image value is a local path (not a web URL), it is resolved under jeecg.path.upload and canonicalized. If the canonical target path does not start with the canonical upload-dir path, the request is rejected. The imageUrl is user/template-influenced, so this is a load-bearing guard -- never weaken it.
Source
Thrown at jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/wordtpl/utils/WordUtil.java:733
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
in = conn.getInputStream();
} catch (IOException e) {
log.error(e.getMessage(), e);
throw new JeecgBootException(e);
}
//update-end---author:wangshuai ---date:2026-05-11 for:[issues/9610]【安全漏洞】修复WordUtil.addImage存储型SSRF漏洞(CWE-918)-----------
} else {
//update-begin---author:liusq ---date:2026-03-30 for:[issues/9429]【安全漏洞】修复WordUtil.addImage路径遍历漏洞(CWE-22)-----------
String uploadPath = SpringContextUtils.getApplicationContext()
.getEnvironment()
.getProperty("jeecg.path.upload", "");
// 将本地图片读取到 InputStream
String filePath = uploadPath + File.separator + imageUrl;
// 路径遍历校验:规范化后确保文件在uploadPath目录内
File uploadDir = new File(uploadPath).getCanonicalFile();
File targetFile = new File(filePath).getCanonicalFile();
if (!targetFile.toPath().startsWith(uploadDir.toPath())) {
throw new JeecgBootException("非法文件路径,禁止访问上传目录之外的文件: " + imageUrl);
}
in = new FileInputStream(targetFile);
//update-end---author:liusq ---date:2026-03-30 for:[issues/9429]【安全漏洞】修复WordUtil.addImage路径遍历漏洞(CWE-22)-----------
}
XWPFRun run = paragraph.createRun();
String display = content.getString("imgDisplay");
if(oConvertUtils.isNotEmpty(display) && display.toLowerCase().startsWith("float-")){
// 浮动图片
String behindDoc = "0";
if(!display.equalsIgnoreCase("float-bottom")){
behindDoc = "1";
}
int width = content.getIntValue("width");
int height = content.getIntValue("height");
View on GitHub (pinned to 96fb33f5ec)
Solutions
- This guard is firing correctly -- inspect the rejected imageUrl payload.
- If the access is legitimate, place the image under jeecg.path.upload and reference it by a relative path inside that dir.
- Do NOT remove or relax the startsWith canonical check.
- Audit logs for repeated attempts (possible attack).
Defensive patterns
Strategy: validation
Validate before calling
// caller-side: ensure image values are relative paths inside the upload dir
String uploadPath = SpringContextUtils.getApplicationContext().getEnvironment()
.getProperty("jeecg.path.upload", "");
File uploadDir = new File(uploadPath).getCanonicalFile();
File target = new File(uploadPath, imageUrl).getCanonicalFile();
if (!target.toPath().startsWith(uploadDir.toPath())) {
throw new SecurityException("拒绝越界路径: " + imageUrl);
} Try / catch
// This is a security guard, not a recoverable error.
// Catch only to log/audit, then deny.
try { addImage(paragraph, content); }
catch (JeecgBootException e) {
if (e.getMessage().contains("非法文件路径")) {
log.warn("[安全审计] 路径遍历尝试被拦截: {}", content.getString("value"));
}
throw e;
} Prevention
- Never accept absolute paths or '../' in image values from user content.
- Treat repeated triggers as a security incident and audit them.
- Do NOT relax the canonical startsWith check.
When it happens
Trigger: A document template's image value contains '../' sequences, an absolute path, or a symlink that resolves outside the upload directory; getCanonicalFile() resolves the path beyond uploadPath.
Common situations: Malicious/templated image path supplied via document content; a symlink in the upload dir escaping it; imageUrl with a leading '/'.
Related errors
- Illegal access to path outside of base directory.
- 非法业务路径,禁止访问上传目录之外的路径: ${bizPath}
- 非法存储路径,路径包含遍历字符: {storePath}
- 文件路径包含非法字符
- 非法文件路径,禁止访问上传目录之外的文件:
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/8ea15f16945fa761.
Report an issue: GitHub.