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

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

问题描述

我需要验证上传文件的文件类型,并且应该只允许 pdf、plain test 和 MS word 文件.这是我的模型和带有验证功能的表单.但是,即使没有扩展名,我也可以上传文件.

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 保存文件.我想在 save() 时它会调用 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天全站免登陆