فایل آپلود شده رو فقط با پسوندش چک می‌کنی؟ بیخیال!

تاحالا شده کاربر فایلی رو آپلود کنه و شما فقط پسوندش ( jpg یا pdf) رو چک کنید و با خوشحالی بگید کار تمومه؟ اگه اینطوره، باید بگم که یه جای کار حسابی می‌لنگه!

کاربر به راحتی می‌تونه یک فایل مخرب (مثلاً یه اسکریپت) رو به virus.png تغییر نام بده و سیستم شما رو دور بزنه.

راه حل چیه؟ کتابخونه python-magic

این پکیج یک رابط (Wrapper) برای کتابخونه قدرتمند libmagic در زبان C هست. کار اصلیش اینه که بیخیال اسم و پسوند فایل بشه و بره سراغ اصل مطلب محتوای خود فایل.

مجیک چند بایت اول یک فایل (که بهش هدر یا Magic Numbers می‌گن) رو می‌خونه و از روی اون امضای دیجیتالی، نوع واقعی فایل رو تشخیص می‌ده.

مثال:

import magic
from django.core.files.uploadedfile import InMemoryUploadedFile

def get_mime_type_from_content(file: InMemoryUploadedFile) -> str:
    """Reads the initial bytes of a file to determine its actual MIME type."""
    try:
        initial_bytes = file.read(2048)
        file.seek(0)
        return magic.from_buffer(initial_bytes, mime=True)
    except Exception as err:
        raise Exception(f"Failed to detect MIME type: {err}")

def check_file_is_image(file: InMemoryUploadedFile) -> bool:
    """Check if the uploaded file is an image based on its MIME type."""
    try:
        mime_type = get_mime_type_from_content(file)
        return mime_type.startswith("image/")
    except Exception as err:
        print(f"[ERROR] check_file_is_image: {err}")
        return False