elunez/eladmin · warning · BadRequestException

只能上传图片

Error message

只能上传图片

What it means

Thrown by LocalStorageController.uploadPicture (POST /localStorage/pictures, no @PreAuthorize on this endpoint in the shown region) when the uploaded file's extension does not map to FileUtil.IMAGE type. The check is extension-based only: FileUtil.getExtensionName on the original filename, then FileUtil.getFileType(suffix) compared to the IMAGE constant.

Source

Thrown at eladmin-tools/src/main/java/me/zhengjie/rest/LocalStorageController.java:78

    public void exportFile(HttpServletResponse response, LocalStorageQueryCriteria criteria) throws IOException {
        localStorageService.download(localStorageService.queryAll(criteria), response);
    }

    @PostMapping
    @ApiOperation("上传文件")
    @PreAuthorize("@el.check('storage:add')")
    public ResponseEntity<Object> createFile(@RequestParam String name, @RequestParam("file") MultipartFile file){
        localStorageService.create(name, file);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @ApiOperation("上传图片")
    @PostMapping("/pictures")
    public ResponseEntity<LocalStorage> uploadPicture(@RequestParam MultipartFile file){
        // 判断文件是否为图片
        String suffix = FileUtil.getExtensionName(file.getOriginalFilename());
        if(!FileUtil.IMAGE.equals(FileUtil.getFileType(suffix))){
            throw new BadRequestException("只能上传图片");
        }
        LocalStorage localStorage = localStorageService.create(null, file);
        return new ResponseEntity<>(localStorage, HttpStatus.OK);
    }

    @PutMapping
    @Log("修改文件")
    @ApiOperation("修改文件")
    @PreAuthorize("@el.check('storage:edit')")
    public ResponseEntity<Object> updateFile(@Validated @RequestBody LocalStorage resources){
        localStorageService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @Log("删除文件")
    @DeleteMapping
    @ApiOperation("多选删除")
    public ResponseEntity<Object> deleteFile(@RequestBody Long[] ids) {

View on GitHub (pinned to 55fbf70595)

Solutions

  1. Upload a genuine image with a standard lowercase extension (jpg/jpeg/png/gif/bmp).
  2. If a legitimate image type is rejected, extend FileUtil's image extension list to include it (and make the comparison case-insensitive).
  3. Use the generic file upload endpoint (POST /localStorage with @PreAuthorize('storage:add')) for non-image files.
  4. Optionally add content sniffing (e.g. checking magic bytes) if extension spoofing matters for your threat model.

Example fix

// before
String suffix = FileUtil.getExtensionName(file.getOriginalFilename());
if(!FileUtil.IMAGE.equals(FileUtil.getFileType(suffix))){
    throw new BadRequestException("只能上传图片");
}

// after: case-insensitive suffix check
String suffix = FileUtil.getExtensionName(file.getOriginalFilename());
String type = StrUtil.isBlank(suffix) ? "" : FileUtil.getFileType(suffix.toLowerCase());
if(!FileUtil.IMAGE.equals(type)){
    throw new BadRequestException("只能上传图片");
}
Defensive patterns

Strategy: validation

Validate before calling

// client-side pre-check mirroring the server rule
const IMAGE_EXT = ['jpg','jpeg','png','gif','bmp','ico'];
const ext = file.name.split('.').pop().toLowerCase();
if (!IMAGE_EXT.includes(ext)) { showToast('只能上传图片'); return; }

Try / catch

try { await uploadPicture(file); } catch (err) { if (err.response?.status === 400 && err.response.data.message === '只能上传图片') { /* prompt user to pick an image */ } }

Prevention

When it happens

Trigger: Uploading a file whose extension is in the document/other category set (e.g. .pdf, .zip, .mp4, .txt, or no extension) to POST /localStorage/pictures; or a filename with trailing spaces/uppercase variants if the extension matcher is case-sensitive (e.g. .JPG not recognized).

Common situations: Frontend file-picker not filtering to images; user renames a non-image to .jpg (passes the check — it only inspects the name, not content); HEIC/WebP or other newer formats missing from the extension list; uppercase extensions from Windows uploads.

Related errors


AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14). Data as JSON: /api/errors/73e44f6bba6a73e3. Report an issue: GitHub.