可能重复:
Django(音频(文件验证
我正在构建一个网络应用程序,用户可以在其中上传媒体内容,包括音频文件。
我在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文件的异常内容?
另一个发布的答案的替代方案,用于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
方法非常严格,实际上可以将编码不正确的文件标记为无效。您必须自己决定这是否适合您的用例。
其想法是使用诸如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实用程序,所以,最好使用另一个。例如,还有诱变剂项目。
更新。
更专业的方法。
- 让用户在并没有验证的情况下上传他的文件
- 创建一个与一个文件关联的特殊模型字段:is_checked。设置字段默认情况下为False
- 不要让其他用户下载具有is_checked==错误
- 组织运行检查未检查文件的反恶意软件软件。软件必须作为Python任务中的函数调用。函数必须回答以下问题:某个特定文件是否包含恶意软件部分
- 如果当前文件包含恶意软件部分,请将其删除,并删除有关文件否则,在任务中设置is_checked=True
为什么是分开的任务?因为这种恶意软件检查可能是一项漫长的操作。