4

重複の可能性:
Django (オーディオ) ファイルの検証

ユーザーがオーディオ ファイルを含むメディア コンテンツをアップロードできる Web アプリを構築しています。

AudioFileUploadFormに、以下を検証するクリーンなメソッドがあります。

  • オーディオ ファイルが大きすぎないこと。
  • 音声ファイルに有効な content_type (MIME タイプ) があること。
  • オーディオ ファイルに有効な拡張子があること。

ただ、セキュリティが心配です。ユーザーが悪意のあるコードを含むファイルをアップロードし、上記の検証を簡単に通過する可能性があります。次にやりたいことは、オーディオ ファイルが実際にオーディオ ファイルであることを検証することです (ディスクに書き込む前に)。

どうすればいいですか?

class UploadAudioForm(forms.ModelForm):
    audio_file = forms.FileField()

    def clean_audio_file(self):
        file = self.cleaned_data.get('audio_file',False):
            if file:
                if file._size > 12*1024*1024:
                    raise ValidationError("Audio file too large ( > 12mb )")
                if not file.content_type in ['audio/mpeg','audio/mp4', 'audio/basic', 'audio/x-midi', 'audio/vorbis', 'audio/x-pn-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio', 'audio/vnd.rn-realaudio', 'audio/wav', 'audio/x-wav']:
                    raise ValidationError("Sorry, we do not support that audio MIME type. Please try uploading an mp3 file, or other common audio type.")
                if not os.path.splitext(file.name)[1] in ['.mp3', '.au', '.midi', '.ogg', '.ra', '.ram', '.wav']:
                    raise ValidationError("Sorry, your audio file doesn't have a proper extension.")
                # Next, I want to read the file and make sure it is 
                # a valid audio file. How should I do this? Use a library?
                # Read a portion of the file? ...?
                if not ???.is_audio(file.content):
                    raise ValidationError("Not a valid audio file.")
                return file
            else:
                raise ValidationError("Couldn't read uploaded file")

編集:「オーディオファイルが実際にオーディオファイルであることを検証する」とは、次のことを意味します。

オーディオ ファイルの典型的なデータを含むファイル。ユーザーが適切なヘッダーを含むファイルをアップロードし、音声データの代わりに悪意のあるスクリプトをアップロードできるのではないかと心配しています。たとえば... mp3ファイルはmp3ファイルですか?それとも、mp3 ファイルの特徴ではないものが含まれていますか?

4

2 に答える 2

5

header解析を行う他の投稿された回答の代替。これは、誰かが有効なヘッダーの背後に他のデータを含めることができることを意味します。

より多くの CPU を消費するが、より厳格なポリシーを持つファイル全体を検証することです。これを実行できるライブラリはpython audiotoolsで、関連する API メソッドはAudioFile.verifyです。

次のように使用します。

import audiotools

f = audiotools.open(filename)
try:
    result = f.verify()
except audiotools.InvalidFile:
    # Invalid file.
    print("Invalid File")
else:
    # Valid file.
    print("Valid File")

警告として、この方法verifyは非常に厳密であり、実際には正しくエンコードされていないファイルを無効としてフラグ付けする可能性があります。これが適切な方法であるかどうかは、自分で判断する必要があります。

于 2013-01-10T18:54:15.777 に答える
1

アイデアは、sndhdrなどのユーティリティを使用して、ファイルのヘッダーを読み取ろうとすることです。

from sndhdr import what
import os
from settings import MEDIA_ROOT
...
if what( os.path.join( MEDIA_ROOT, file.name ) ) == None:
# header parse failed, so, it could be a non-audio file.

この場合、ユーティリティが非オーディオ ファイルをオーディオ ファイルとして認識できなかったことを確認する必要があります。

私は sndhdr ユーティリティを使用したことがないので、別のユーティリティを使用した方がよいかもしれません。たとえば、変異原プロジェクトもあります。

更新します

より専門的なアプローチ。

  1. ユーザーがそのような検証なしでファイルをアップロードできるようにします。
  2. is_checked という 1 つのファイルに関連付けられた特別なモデル フィールドを作成します。デフォルトでは、フィールドを False に設定します。
  3. is_checked == False を持つファイルを他のユーザーにダウンロードさせないでください
  4. 未チェックのファイルをチェックするマルウェア対策ソフトウェアを実行する非同期タスクを編成します。ソフトウェアは、pythonic タスクから関数として呼び出す必要があります。この関数は、特定のファイルにマルウェアの部分があるかどうかという質問に答える必要があります。
  5. 現在のファイルにマルウェア部分がある場合は、それを削除し、ファイルに関する記録を削除します。それ以外の場合は、タスクから is_checked = True を設定します。

なぜ別のタスクなのですか?このようなマルウェアのチェックは長時間の操作になる可能性があるためです。

于 2013-01-10T18:45:58.583 に答える