{"record":{"id":"7a337dd76b6c36a1","repo":"jeecgboot/JeecgBoot","slug":"e-getmessage-7a337d","errorCode":null,"errorMessage":"${e.getMessage()}","messagePattern":"\\$\\{e\\.getMessage\\(\\)\\}","errorType":"exception","errorClass":"JeecgBootException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCommentServiceImpl.java","lineNumber":136,"sourceCode":"    }\n\n    @Transactional(rollbackFor = Exception.class)\n    @Override\n    public void saveOneFileComment(HttpServletRequest request) {\n        String existFileId = request.getParameter(\"fileId\");\n        if(oConvertUtils.isEmpty(existFileId)){\n            String savePath = \"\";\n            // 获取业务路径\n            String bizPath = request.getParameter(\"biz\");\n            // 获取上传文件对象\n            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;\n            MultipartFile file = multipartRequest.getFile(\"file\");\n\n            // 文件安全校验，防止上传漏洞文件\n            try {\n                SsrfFileTypeFilter.checkUploadFileType(file, bizPath);\n            } catch (Exception e) {\n                throw new JeecgBootException(e);\n            }\n\n            if (oConvertUtils.isEmpty(bizPath)) {\n                bizPath = CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType) ? \"upload\" : \"\";\n            }\n            if (CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)) {\n                savePath = this.uploadLocal(file, bizPath);\n            } else {\n                savePath = CommonUtils.upload(file, bizPath, uploadType);\n            }\n\n            String orgName = file.getOriginalFilename();\n            // 获取文件名\n            orgName = CommonUtils.getFileName(orgName);\n            //文件大小\n            long size = file.getSize();\n            //文件类型\n            String type = orgName.substring(orgName.lastIndexOf(\".\"), orgName.length());","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCommentServiceImpl.java#L118-L154","documentation":"In the comment-attachment upload path, SsrfFileTypeFilter.checkUploadFileType validates the file extension/type and the bizPath before storage. Any failure is re-wrapped as JeecgBootException(e); because JeecgBootException(Throwable) delegates getMessage() to the cause, the surfaced message is the filter's own message (e.g. '上传失败，存在非法文件类型：xxx', '上传业务路径包含非法字符！', '上传业务路径深度超出限制！').","triggerScenarios":"Uploading a disallowed extension (e.g. .exe, .jsp, .sh, .svg); a bizPath containing traversal/illegal characters; a bizPath whose depth exceeds the configured limit; bizPath null where a value is required.","commonSituations":"Restrictive extension allowlist blocking a legitimate business file type; client sending a crafted or user-controlled bizPath; missing/typo bizPath from the frontend; SSRF guard rejecting a host in a URL-based path.","solutions":["Read the wrapped message to identify which specific check failed (file type vs path char vs depth).","Use an allowed file extension; if a legitimate type is blocked, extend the allowlist in the jeecg config.","Sanitize bizPath: no ../, no illegal characters, within the configured depth limit.","Never pass raw user input as bizPath."],"exampleFix":"// before\nString biz = request.getParameter(\"biz\"); // may contain ../\nSsrfFileTypeFilter.checkUploadFileType(file, biz); // throws\n// after\nString biz = sanitizeBizPath(request.getParameter(\"biz\"));\n// sanitizeBizPath strips ../, leading slashes, and enforces a fixed allowlist of folders\nSsrfFileTypeFilter.checkUploadFileType(file, biz);","handlingStrategy":"validation","validationCode":"// Validate extension and bizPath against the same rules the filter enforces, BEFORE uploading.\nString ext = FilenameUtils.getExtension(file.getOriginalFilename()).toLowerCase();\nif (!ALLOWED_EXTENSIONS.contains(ext)) {\n    return Result.error(\"不支持的文件类型: \" + ext);\n}\nString bizPath = sanitizeBizPath(request.getParameter(\"biz\")); // no ../, no illegal chars, depth-checked\nif (bizPath == null) {\n    return Result.error(\"业务路径非法\");\n}","typeGuard":"public boolean isUploadAllowed(MultipartFile f, String bizPath) {\n    try {\n        SsrfFileTypeFilter.checkUploadFileType(f, bizPath);\n        return true;\n    } catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    sysCommentService.uploadCommentFile(request, ...);\n} catch (JeecgBootException e) {\n    // e.getMessage() is the filter's specific reason\n    return Result.error(\"文件上传被拒: \" + e.getMessage());\n}","preventionTips":["Sanitize bizPath server-side from an allowlist; never pass raw user input.","Restrict uploads to the minimum set of extensions your feature needs.","Surface the wrapped filter message to the user so they know which rule failed."],"tags":["upload","security","file-type","path-traversal"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}