在Django中验证上传的文件

时间:2009-11-17 00:12:02

标签: python django security file-upload

我正在使用的Django应用程序具有Event模型。 Event可能包含相关照片,静态html文件和pdf文件。

我希望允许受信任的用户上传这些文件,但我对安全性持谨慎态度,尤其是阅读了以下in the Django docs(链接)。

  

请注意,无论何时处理   上传文件,你应该付清   注意你上传的地方   他们和他们是什么类型的文件,   避免安全漏洞。验证所有   上传文件,以便您确定   文件是你认为的。对于   例如,如果你盲目地让某人   上传文件,无需验证,即可   您网站中的目录   服务器的文档根,然后是某人   可以上传CGI或PHP脚本   通过访问它来执行该脚本   您网站上的网址。不要允许。

如何验证不同类型的文件?我很想听听任何人处理这种事情的经历,或者是进一步阅读的链接。我有一种直觉,认为html文件风险太大,在这种情况下我会限制管理员的上传权限。

6 个答案:

答案 0 :(得分:16)

所有答案都集中在验证文件上。这几乎是不可能的。

Django开发人员并没有要求您验证文件是否可以作为 cgi文件执行。他们只是告诉你不要把它们放在被执行的地方。

你应该将所有Django内容放在一个特殊的Django目录中。 Django代码目录不应包含静态内容。 不要将用户文件放在Django源存储库中。

如果您使用的是Apache2,请查看基本的cgi教程:http://httpd.apache.org/docs/2.0/howto/cgi.html

Apache2可能会设置为运行ScriptAlias文件夹中的任何文件。 请勿将用户文件放在/cgi-bin//usr/local/apache2/cgi-bin/文件夹中。

Apache2可能设置为服务器cgi文件,具体取决于AddHandler cgi-script设置。 请勿让用户提交包含.cgi.pl等扩展名的文件。

但是,您需要清理用户提交的文件,以便在其他客户端的计算机上安全运行提交的HTML对其他用户不安全。这不会对您的服务器造成伤害。您的服务器只会向任何请求它的人吐回来。获取HTML清理程序。

此外, SVG可能不安全。它过去有虫子。 SVG是一个带有javascript的XML文档,因此它可能是恶意的。

PDF很......很棘手。您可以将其转换为图像(如果您真的必须),或者提供图像预览(并让用户自行下载),但对于尝试使用它的人来说会很痛苦。

考虑一个好的文件的白名单。嵌入在gif,jpeg或png文件中的病毒看起来就像是一张损坏的图片(或者无法显示)。如果你想成为偏执狂,请使用PIL将它们全部转换为标准格式(嘿,你也可以检查大小)。清理HTML应该没问题(剥离脚本标签不是火箭科学)。如果消毒是吸吮周期(或者你只是谨慎),我猜你可以把它放在一个单独的服务器上。

答案 1 :(得分:14)

对于图像,您可以使用Python Imaging Library(PIL)。

Image.open(filepath)

如果文件不是图像,则会抛出异常。我对Python / Django很陌生,所以其他人可能有更好的方法来验证图像。

答案 2 :(得分:6)

您要对上传的内容做的第一件事就是将其存储在无法直接下载的目录中。如果您的应用程序存在于~/www/中,请考虑将数据放在'〜/ data /`。

第二,您需要确定用户上传的文件类型,然后为每种文件类型创建规则。

您无法信任基于扩展名的文件,因此请使用Fileinfo之类的内容。然后,对于每个mime类型,创建一个验证器。 ImageMagick可以验证图像文件。为了提高安全性,您可能必须在pdf和flash文件等文件上运行病毒扫描程序。对于html,您可能需要考虑限制标记的子集。

我找不到Fileinfo模块的Python等价物,尽管总是可以执行/usr/bin/file -i。大多数允许上传的系统会创建内容名称或ID。然后,他们使用mod_rewrite来解析URL,并在磁盘上查找内容。找到内容后,会使用sendfile或类似内容将其返回给用户。例如,在内容获得批准之前,可能只允许上传内容的用户查看内容。

答案 3 :(得分:5)

这有点特定于您的托管环境,但这就是我所做的:

使用Nginx代替apache提供所有用户上传的内容,并将其全部作为静态内容提供(即使用户上传,也不会运行任何php或cgi)

答案 4 :(得分:2)

'可信用户'是一个主观用语。是您亲自了解的人还是仅在您的应用上创建了帐户的人?不要将您的文件系统访问权限提供给您不熟悉的人。

赋予某人上传文件的能力在任何情况下都有点危险,我认为应该避免。上周我遇到了类似的问题,自动上传了html代码,我决定将它存储在数据库中。我认为在大多数情况下,您可以使用数据库而不是文件系统。

验证的一个问题是您必须为任何类型的文件编写新的验证器。它可能是未来的限制,在某些情况下是一项重大任务。

因此,我建议重新考虑基于数据库的设计。

答案 5 :(得分:0)

您可以使用BeautifulSoup

验证html文件