Django - 已上传文件类型验证 [英] Django - Uploaded file type validation

查看:382
本文介绍了Django - 已上传文件类型验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要验证上传文件的文件类型,只允许使用pdf,纯文本和MS文件。这是我的模型和具有验证功能的形式。但是,即使没有扩展名,我也可以上传文件。

I need to validate the file type of the uploaded file and should allow only pdf, plain test and MS word files. Here is my model and and the form with validation function. But, I'm able to upload files even without the extension.

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 。我以为while()它会调用clean_content并进行内容类型验证。我猜,clean_content根本就没有调用验证。

In my view, I'm just saving the file from the request.FILE. I thought while save() it'll call the clean_content and do content-type validation. I guess, the clean_content is not at all calling for validation.

推荐答案

你的方法不行:作为攻击者,我可以只需伪造HTML标题即可向您发送任何带有MIME类型 text / plain 的任何内容。

You approach will not work: As an attacker, I could simply forge the HTML header to send you anything with the mime type text/plain.

正确的解决方法是在Unix上使用 file(1)这样的工具来检查文件的内容以确定它是什么。请注意,没有一个好方法来知道某些东西是否是纯文本。如果文件以16位Unicode格式保存,纯文本甚至可以包含0个字节。

The correct solution is to use a tool like file(1) on Unix to examine the content of the file to determine what it is. Note that there is no good way to know whether something is really plain text. If the file is saved in 16 bit Unicode, the "plain text" can even contain 0 bytes.

查看此问题的选项如何执行此操作:如何在python中找到文件的MIME类型?

See this question for options how to do this: How to find the mime type of a file in python?

这篇关于Django - 已上传文件类型验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆