[critical] Arbitrary server file read via cover_url (local-path branch in download_and_store_cover) #5

Closed
opened 2026-10-18 15:51:55 +00:00 by jfro · 0 comments
Owner

Severity: critical
Affects: main (also present on jtk/ebook-management)

Files: lib/fuzzy_catalog/storage.ex:144-148 (+ store_local_cover :176), lib/fuzzy_catalog_web/controllers/book_controller.ex:569-583 (called from add_from_lookup :110, scan_barcode :181, batch_add :406)
Any logged-in user posts book[cover_url]=/etc/passwd (or the release env / config files) to /books/add-from-lookup. File.exists?(url) is true, so the file is read and stored as covers/.jpg (unknown ext falls back to image/jpeg, which passes the type check), then served by Plug.Static at /uploads/covers/.jpg with no auth. With registration on by default this is close to unauthenticated.
Fix: never treat request input as a local path. Only accept http/https URLs in download_cover_from_params; move the local-file path to a separate function used only by the sync code, restricted to configured library dirs. Check image magic bytes before storing (detect_image_format_from_data exists already).


Found by Nye's audit, 2026-10-18 (static review of main @1d89af4 and jtk/ebook-management @43a849e).

**Severity:** critical **Affects:** main (also present on jtk/ebook-management) Files: lib/fuzzy_catalog/storage.ex:144-148 (+ store_local_cover :176), lib/fuzzy_catalog_web/controllers/book_controller.ex:569-583 (called from add_from_lookup :110, scan_barcode :181, batch_add :406) Any logged-in user posts book[cover_url]=/etc/passwd (or the release env / config files) to /books/add-from-lookup. `File.exists?(url)` is true, so the file is read and stored as covers/<uuid>.jpg (unknown ext falls back to image/jpeg, which passes the type check), then served by Plug.Static at /uploads/covers/<uuid>.jpg with no auth. With registration on by default this is close to unauthenticated. Fix: never treat request input as a local path. Only accept http/https URLs in download_cover_from_params; move the local-file path to a separate function used only by the sync code, restricted to configured library dirs. Check image magic bytes before storing (detect_image_format_from_data exists already). --- _Found by Nye's audit, 2026-10-18 (static review of main @1d89af4 and jtk/ebook-management @43a849e)._
jfro closed this issue 2026-10-18 16:14:54 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jfro/fuzzy_catalog#5
No description provided.