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

  1. This guard is firing correctly -- inspect the rejected imageUrl payload.
  2. If the access is legitimate, place the image under jeecg.path.upload and reference it by a relative path inside that dir.
  3. Do NOT remove or relax the startsWith canonical check.
  4. 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

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


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/8ea15f16945fa761. Report an issue: GitHub.