File Type Checks (Magic Number) – Django

python-magic is a Python interface to the libmagic file type identification library. libmagic identifies file types by checking their headers according to a predefined list of file types.

Installation

Windows

pip3 install python-magic-bin

Debian/Ubuntu

sudo apt-get install libmagic1

Django (PYTHON )

Example

views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect
from .forms import ResumeForm

import magic

# Create your views here.
def upload_resume(request):
    if request.method == 'POST':
    	form = ResumeForm(request.POST, request.FILES)
    	if form.is_valid():
            form.save()
            return HttpResponseRedirect("/") 
    else:
        form = ResumeForm
    return render(request, 'upload.html', {'form':form})


allowed_file_type = ['image/jpeg', 'image/png', 'image/gif']
def handle_upload(request):
    if request.method == 'POST':
    	# check the file type
    	form = ResumeForm(request.POST, request.FILES)
    	file = request.FILES['file']
    	file_type = magic.from_buffer(file.read(), mime=True)
    	if file_type not in allowed_file_type:
            return render(request, 'upload.html', {'form': form, 'ft': file_type, 'fta':allowed_file_type, 'st':'This file type could not be uploaded.'})

    	#handle the uploaded file here
    	form.save()
    	return render(request, 'upload.html', {'form': form, 'ft': file_type, 'fta':allowed_file_type, 'st':'This file type could be uploaded.'})
    else:
        form = ResumeForm

    return render(request, 'upload.html', {'form': form})

forms.py

from django import forms
from .models import Resume

class ResumeForm(forms.ModelForm):

   class Meta:
      model = Resume
      fields = ['file']

model.py

from django.db import models


# Create your models here.

class Resume(models.Model):
    file = models.FileField(upload_to= 'members/',null=True)
    
    def __repr__(self):
        return 'Resume(%s, %s)' % (self.name, self.file)

    def __str__ (self):
        return self.name

settings.py

import os

MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

Descriptions

The magic module is a library for detecting the MIME type of a file. The from_buffer() function is used to determine the MIME type of a file by passing in the contents of the file as a bytes object. The optional mime argument, if set to True, will also return the encoding of the file.

import magic

file_type = magic.from_buffer(file.read(), mime=True)

This code appears to be part of a function that handles file uploads. The function first checks if the file type of the uploaded file is in a list of allowed file types. If the file type is not allowed, the function calls the render function to render an HTML template called upload.html with a message indicating that the file type could not be uploaded.

allowed_file_type = ['image/jpeg', 'image/png', 'image/gif']

if file_type not in allowed_file_type:
            return render(request, 'upload.html', {'form': form, 'ft': file_type, 'fta':allowed_file_type, 'st':'This file type could not be uploaded.'})

This code appears to be part of a function that handles file uploads. If the file type of the uploaded file is allowed (as determined by the previous if statement), this code is executed.

The first line saves the uploaded file using the save method of the form object.

The second line calls the render function to render an HTML template called upload.html with a message indicating that the file type was successfully uploaded. As in the previous code block, the render function takes in a request object, the name of the template, and a context dictionary containing variables that will be available in the template. In this case, the context dictionary includes the form object, the file_type and allowed_file_type variables, and a status message indicating that the file type was successfully uploaded.

#handle the uploaded file here
form.save()
return render(request, 'upload.html', {'form': form, 'ft': file_type, 'fta':allowed_file_type, 'st':'This file type could be uploaded.'})

Proof Of Concepts (POC)

(1) Upload .jpg

A file was uploaded.

(2) Upload .txt

A file could not be uploaded.

(3) Upload a text file which a file type was changed to .png

A file could not be uploaded.

Reference