Skip to content

Add optional MIME type validation for uploaded files using libmagic #110

@youichi-uda

Description

@youichi-uda

Summary

Add an optional feature to validate uploaded file MIME types using libmagic (python-magic), rather than relying solely on client-supplied Content-Type headers.

Motivation

Currently, Django's MultiPartParser accepts the Content-Type header provided by the client without validation (see django/http/multipartparser.py, lines 275-278). While this is documented behavior and developers are responsible for sanitizing user input, many developers are unaware of this and trust UploadedFile.content_type for file type validation.

This can lead to security issues when:

  • Developers use content_type to restrict uploads (e.g., "only accept images")
  • Applications serve uploaded files with the original Content-Type
  • File processing pipelines make decisions based on content_type

Proposal

Add an optional libmagic-based MIME type detection to UploadedFile:

# Option 1: New method
uploaded_file.detected_content_type  # Returns libmagic-detected MIME type

# Option 2: Setting to enable validation
# settings.py
FILE_UPLOAD_VALIDATE_CONTENT_TYPE = True  # Validates Content-Type matches actual file

Considerations

  • Dependency: python-magic would be an optional dependency
  • Performance: Magic byte detection adds overhead; should be opt-in
  • Backwards compatibility: Existing behavior unchanged by default

Prior Art

  • Flask/Werkzeug: Developers commonly use python-magic manually
  • Rails: Active Storage has built-in content type detection
  • Laravel: Has MIME type validation rules

Context

This suggestion came from a discussion with the Django Security Team regarding Content-Type handling in file uploads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Django CoreThis idea is suitable for inclusion in Django itself.

    Type

    No type

    Projects

    Status

    Idea

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions