Django的 - 上传的文件类型验证(Django - Uploaded file type va

2019-09-20 12:31发布

我需要验证上传文件的文件类型,应只允许PDF,平原测试和MS Word文件。 这里是我的模型,并与验证功能的形式。 但是,我能上传文件,即使不带扩展名。

class Section(models.Model):
    content = models.FileField(upload_to="documents")

class SectionForm(forms.ModelForm):
    class Meta:
        model = Section
    FILE_EXT_WHITELIST = ['pdf','text','msword']

    def clean_content(self):
        content = self.cleaned_data['content']
        if content:
            file_type = content.content_type.split('/')[0]
            print file_type
            if len(content.name.split('.')) == 1:
                raise forms.ValidationError("File type is not supported.")
            if content.name.split('.')[-1] in self.FILE_EXT_WHITELIST:
                return content
            else:
                raise forms.ValidationError("Only '.txt' and '.pdf' files are allowed.")

下面是这个视图,

def section_update(request, object_id):
    section = models.Section.objects.get(pk=object_id)
    if 'content' in request.FILES:
            if request.FILES['content'].name.split('.')[-1] == "pdf":
                content_file = ContentFile(request.FILES['content'].read())
                content_type = "pdf"
                section.content.save("test"+'.'+content_type , content_file)
                section.save()

在我看来,我只是保存来自文件request.FILE 。 我想同时保存(),它会调用clean_content和做内容类型的验证。 我想,在clean_content完全不要求验证。

Answer 1:

你的方法将行不通:作为一个攻击者,我可以简单地伪造HTML头送你的MIME类型的任何text/plain

正确的解决方法是使用像一个工具file(1)在Unix上检查文件的内容,以确定它是什么。 需要注意的是,有知道的东西是否真的明文没有什么好办法。 如果文件被保存在16位Unicode中,“纯文本”,甚至包含0字节。

看到这个问题的选项,如何做到这一点: 如何找到Python中的文件的MIME类型?



Answer 2:

您可以使用Python魔法

import magic
magic.from_file('/my/file.jpg', mime=True)
# image/jpeg


文章来源: Django - Uploaded file type validation