{"record":{"id":"fef6256789f507e5","repo":"jeecgboot/JeecgBoot","slug":"suffix","errorCode":null,"errorMessage":"下载失败，存在非法文件类型：{suffix}","messagePattern":"下载失败，存在非法文件类型：(.+?)","errorType":"validation","errorClass":"JeecgBootException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java","lineNumber":161,"sourceCode":"     */\n    private static String getFileTypeBySuffix(String fileName) {\n        return fileName.substring(fileName.lastIndexOf(\".\") + 1, fileName.length());\n    }\n\n\n    /**\n     * 下载文件类型过滤\n     *\n     * @param filePath\n     */\n    public static void checkDownloadFileType(String filePath) throws IOException {\n        //文件后缀\n        String suffix = getFileTypeBySuffix(filePath);\n        log.debug(\" 【文件下载校验】文件后缀 suffix: {}\", suffix);\n        boolean isAllowExtension = FILE_TYPE_WHITE_LIST.contains(suffix.toLowerCase());\n        //是否允许下载的文件\n        if (!isAllowExtension) {\n            throw new JeecgBootException(\"下载失败，存在非法文件类型：\" + suffix);\n        }\n    }\n\n    /**\n     * 上传文件类型过滤\n     *\n     * @param file\n     */\n    public static void checkUploadFileType(MultipartFile file) throws Exception {\n        checkUploadFileType(file, null);\n    }\n    \n    /**\n     * 上传文件类型过滤\n     *\n     * @param file\n     */\n    public static void checkUploadFileType(MultipartFile file, String customPath) throws Exception {","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java#L143-L179","documentation":"Thrown by SsrfFileTypeFilter.checkDownloadFileType when the file's extension (lowercased) is not in FILE_TYPE_WHITE_LIST. This is a deny-by-default extension whitelist applied to download endpoints to stop retrieval of dangerous file types (jsp, exe, sh, etc.). Returns JeecgBootException.","triggerScenarios":"A download request (e.g. /sys/download, sys/files/download) for a file whose suffix is not whitelisted — .jsp, .sh, .bat, .exe, .war, .config, or a file with no extension. Also fires for case variants since the check lowercases the suffix.","commonSituations":"A user uploaded a file type the admin later removed from the whitelist; a migration imported legacy files with non-whitelisted extensions; an attacker probing for sensitive file downloads.","solutions":["Add the legitimate extension to FILE_TYPE_WHITE_LIST in SsrfFileTypeFilter (if the type is genuinely safe to serve).","Re-save or convert the file to a whitelisted type (e.g. rename .jpeg to .jpg if jpg is whitelisted).","Confirm the download URL references the intended file and not one with a stripped/doubled extension.","Audit the whitelist with security before expanding it — do not add executable types."],"exampleFix":"// before\n// FILE_TYPE_WHITE_LIST = [jpg, png, pdf]\n// user requests report.jxls -> 下载失败，存在非法文件类型\n\n// after (if approved)\nFILE_TYPE_WHITE_LIST.add(\"jxls\");","handlingStrategy":"validation","validationCode":"String suffix = filePath.substring(filePath.lastIndexOf('.')+1).toLowerCase();\nif (!FILE_TYPE_WHITE_LIST.contains(suffix)) throw new IllegalArgumentException(\"not allowed\");","typeGuard":"public static boolean downloadAllowed(String path){\n    String s = path.substring(path.lastIndexOf('.')+1).toLowerCase();\n    return FILE_TYPE_WHITE_LIST.contains(s);\n}","tryCatchPattern":"try { SsrfFileTypeFilter.checkDownloadFileType(path); }\ncatch (JeecgBootException e) { return ResponseEntity.badRequest().body(e.getMessage()); }","preventionTips":["Keep the whitelist under config so it can change without redeploy.","Reject files with no extension.","Audit whitelist expansions."],"tags":["file-upload","security","file-type","validation","jeecg-boot"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}