Fixes #20236: Improve file naming and upload handling #1282

Closed
opened 2026-04-05 22:55:13 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @pheus on 9/10/2025

Fixes: #20236

Summary
Silently normalize the on‑disk filename derived from image attachments to prevent nested directories and path traversal, while preserving the user‑entered name in the database/UI unchanged.

What’s changed

  • In upload_to:
    • Normalize browser paths (e.g. C:\fakepath\photo.jpg) and extract the real uploaded extension.
    • Use the user‑entered name when present; sanitize via Django’s filename utility.
    • Prefix with {object_type.model}_{object_id} and validate the final relative path with validate_file_name(..., allow_relative_path=True).
    • Preserve only known image extensions (bmp, gif, jpeg, jpg, png, webp); otherwise save without an extension.
  • (Hardening) Guard filename parsing to avoid IndexError if older files don’t follow the expected underscore pattern.

Behavior before

  • Supplying slashes in the name could create subdirectories and trigger IndexError in code that assumes a fixed filename layout.

Behavior after

  • Files are always stored under image-attachments/ with a flat, safe basename.
  • The value shown/stored in the name field is not altered; only the on‑disk filename is normalized.

Notes for reviewers

  • This follows the maintainer guidance to silently normalize rather than reject slashes.
  • No user‑visible changes to the name field or forms.
*Originally created by @pheus on 9/10/2025* ### Fixes: #20236 **Summary** Silently normalize the **on‑disk filename** derived from image attachments to prevent nested directories and path traversal, while preserving the **user‑entered `name`** in the database/UI unchanged. **What’s changed** - In `upload_to`: - Normalize browser paths (e.g. `C:\fakepath\photo.jpg`) and extract the real uploaded extension. - Use the user‑entered `name` when present; sanitize via Django’s filename utility. - Prefix with `{object_type.model}_{object_id}` and validate the final relative path with `validate_file_name(..., allow_relative_path=True)`. - Preserve only known image extensions (`bmp`, `gif`, `jpeg`, `jpg`, `png`, `webp`); otherwise save without an extension. - (Hardening) Guard filename parsing to avoid `IndexError` if older files don’t follow the expected underscore pattern. **Behavior before** - Supplying slashes in the `name` could create subdirectories and trigger `IndexError` in code that assumes a fixed filename layout. **Behavior after** - Files are always stored under `image-attachments/` with a flat, safe basename. - The value shown/stored in the `name` field is **not altered**; only the on‑disk filename is normalized. **Notes for reviewers** - This follows the maintainer guidance to **silently normalize** rather than reject slashes. - No user‑visible changes to the `name` field or forms.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/netbox#1282