{"record":{"id":"df15249820eb8988","repo":"jeecgboot/JeecgBoot","slug":"suffix-df1524","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":188,"sourceCode":"    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 {\n        //1. 路径安全校验\n        validatePathSecurity(customPath);\n        //2. 校验文件后缀和头\n        String suffix = getFileType(file, customPath);\n        log.info(\"【文件上传校验】文件后缀 suffix: {}，customPath：{}\", suffix, customPath);\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     * @return 文件类型\n     * @throws Exception\n     */\n\n    private static String getFileType(MultipartFile file, String customPath) throws Exception {\n        // 代码逻辑说明: [issue/4672]方法造成的文件被占用，注释掉此方法tomcat就能自动清理掉临时文件\n        String fileExtendName = null;\n        InputStream is = null;\n        try {\n            //is = new FileInputStream(file);\n            is = file.getInputStream();","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/SsrfFileTypeFilter.java#L170-L206","documentation":"Thrown by SsrfFileTypeFilter.checkUploadFileType after validatePathSecurity passes but the detected file suffix (from getFileType, which combines extension + magic-header check) is not in FILE_TYPE_WHITE_LIST. This is the upload-side deny-by-default whitelist that prevents uploading executable/unsafe types.","triggerScenarios":"Uploading a file whose extension is not whitelisted (.jsp, .sh, .exe, .html), a file whose header magic does not match its claimed extension (polyglot detection), or a file with a double extension where the resolved type is blocked.","commonSituations":"User uploads a document format the system was not configured to accept; an attacker disguises an executable with an image extension; whitelist was tightened by a security patch and old file types now fail.","solutions":["If the file type is legitimate, add its extension to FILE_TYPE_WHITE_LIST after a security review.","Have the user convert the file to a whitelisted type before uploading.","Verify the file's actual content type matches its extension — re-export the file cleanly.","Do not loosen the whitelist to accept executable/script types; serve those out-of-band instead."],"exampleFix":"// before\n// whitelist = [jpg,png,pdf,xlsx]\nupload.resume.docx  // -> 上传失败，存在非法文件类型\n\n// after (if approved)\nFILE_TYPE_WHITE_LIST.add(\"docx\");","handlingStrategy":"validation","validationCode":"String suffix = FilenameUtils.getExtension(file.getOriginalFilename()).toLowerCase();\nif (!FILE_TYPE_WHITE_LIST.contains(suffix)) reject();","typeGuard":"public static boolean uploadAllowed(MultipartFile f){\n    String s = FilenameUtils.getExtension(f.getOriginalFilename()).toLowerCase();\n    return FILE_TYPE_WHITE_LIST.contains(s);\n}","tryCatchPattern":"try { SsrfFileTypeFilter.checkUploadFileType(file, customPath); }\ncatch (Exception e) { result.error500(e.getMessage()); }","preventionTips":["Validate extension AND magic header (the filter already does both).","Never accept executable types.","Make the whitelist configurable."],"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"}