6

アップロードされたファイルのファイルタイプを検証する必要があり、PDF、プレーンテスト、およびMSWordファイルのみを許可する必要があります。これが私のモデルと検証機能付きのフォームです。ただし、拡張子がなくてもファイルをアップロードできます。

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は検証をまったく要求していません。

4

3 に答える 3

5

あなたのアプローチは機能しません:攻撃者として、私は単にHTMLヘッダーを偽造して、mimeタイプの何かを送信することができますtext/plain

正しい解決策は、Unixのようなツールを使用しfile(1)てファイルの内容を調べ、それが何であるかを判断することです。何かが本当にプレーンテキストであるかどうかを知る良い方法はないことに注意してください。ファイルが16ビットUnicodeで保存されている場合、「プレーンテキスト」には0バイトを含めることもできます。

これを行う方法のオプションについては、この質問を参照してください:Pythonでファイルのmimeタイプを見つける方法は?

于 2012-08-02T08:22:12.600 に答える
2

python-magicを使用できます

import magic
magic.from_file('/my/file.jpg', mime=True)
# image/jpeg
于 2019-01-06T12:58:44.853 に答える
0

これは古い質問ですが、コメントで言及されている後のユーザーの主な質問は、フィールド検証が行われない理由であり、djangoドキュメントで説明されているように、is_valid()を呼び出すとフィールド検証が実行されます。したがって、フィールド検証をアクティブにするには、以下の何かを使用する必要があります。

section = models.Section.objects.get(pk=object_id)    
if request.method == 'POST':    
   form = SectionForm(request.POST, request.FILES)
   if form.is_valid:
      do_something_with_form

フォームの検証は、データがクリーンアップされるときに行われます。このプロセスをカスタマイズしたい場合は、変更を加えるためのさまざまな場所があり、それぞれが異なる目的を果たします。フォーム処理では、3種類のクリーニング方法が実行されます。これらは通常、フォームでis_valid()メソッドを呼び出すときに実行されます

于 2021-04-15T14:12:28.507 に答える