Skip to content

fix: check type and content of uploaded images - #78

Merged
firefly-cpp merged 1 commit into
mainfrom
fix/image-type
Nov 8, 2026
Merged

firefly-cpp merged 1 commit into
mainfrom
fix/image-type

Conversation

@firefly-cpp

Copy link
Copy Markdown
Owner

Problem

With format='image', any uploaded file was stored, including executables, HTML files and scripts renamed to .jpg. Some related issues:

Upload Before After
x.exe, x.html 200, stored 400 File type ".exe" is not allowed (allowed: ...)
Script renamed to x.jpg 200, stored 400 The content of the uploaded file does not match its extension (.jpg).
PNG content named x.jpg 200, stored 400 (content does not match extension)
Empty file 200, stored 400 The uploaded file is empty.
Missing or misnamed file field 400, HTML error page 400 No file was uploaded in the "image" field. (JSON)
JPEG without a filename (e.g. ESP32-CAM) 200, stored without extension 200, stored as ..._upload.jpg
Same filename twice in the same second second upload silently overwrote the first stored as ..._photo_1.jpg
Valid a.jpg, a.JPG, a.png 200 200 (unchanged)

Changes

  • New optional setting allowed_extensions for the image entry in the configuration. Default: jpg, jpeg, png, gif, bmp, webp, tif, tiff. Values are normalised (case, leading dot) and validated at startup.
  • Processing.image_type() detects JPEG, PNG, GIF, BMP, WebP and TIFF from the file signature (no new dependency).
  • Processing.check_image() requires an allowed extension and, for these known types, matching content. Other allowed extensions (e.g. heic) are checked by extension only.
  • The password check still runs before the file is inspected or stored.

Docs

README and getting started describe allowed_extensions, the content check, files without an extension and the naming of stored files.

Tests

  • New TestImageUpload (signatures, valid images, files without extension, rejected files, missing field, no overwrite, configured and invalid allowed_extensions). They fail on the previous code.
  • test_process_image used the text Test image data as a .jpg file, which is exactly what is now rejected; its content now starts with the JPEG signature. The rest of the test is unchanged.
  • Full suite: 45 passed.

Compatibility

Uploads of real images in the default formats behave as before. Uploads of other file types (e.g. .pdf, .heic, .raw) are now rejected unless added to allowed_extensions.


Generated by Claude Code

Any file was accepted for the 'image' format, including executables,
HTML and scripts renamed to .jpg.

- Accept only allowed extensions; by default jpg, jpeg, png, gif, bmp,
  webp, tif and tiff, configurable with "allowed_extensions"
- Check the file signature for known image types, so the content must
  match the extension (a script renamed to .jpg is rejected)
- Accept files without an extension (e.g. ESP32-CAM) if their content
  is an allowed image, and add the matching extension
- Reject empty files
- Return 400 with a JSON message when the file field is missing,
  instead of an HTML error page
- Do not overwrite an image uploaded with the same name in the same
  second; add a counter instead
- Document the new setting and add tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCvw8haRnmyrVKrLkz5Yf8
@firefly-cpp
firefly-cpp merged commit 7b8ffb0 into main Nov 8, 2026
12 checks passed
@firefly-cpp
firefly-cpp deleted the fix/image-type branch November 8, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants