فایل آپلود شده رو فقط با پسوندش چک میکنی؟ بیخیال!
تاحالا شده کاربر فایلی رو آپلود کنه و شما فقط پسوندش ( 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