代码之家  ›  专栏  ›  技术社区  ›  Alasdair

正在验证Django中上载的文件

  •  21
  • Alasdair  · 技术社区  · 16 年前

    我正在工作的django应用程序有一个 Event 模型。安 事件 可能有关联的照片、静态HTML文件和PDF文件。

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

    请注意,无论何时处理 上传的文件,你应该支付关闭 注意你上传的内容 它们以及它们是什么类型的文件, 以避免安全漏洞。验证所有 上传文件,以便您确定 文件就是你所认为的。为了 例如,如果你盲目地让某人 将未经验证的文件上载到 你网站上的目录 服务器的文档根目录,然后是某人 可以上传一个CGI或PHP脚本, 通过访问 网站上的URL。不允许这样做。

    如何验证不同类型的文件?我有兴趣听到任何人处理这类事情的经验,或进一步阅读的链接。我有种直觉,认为HTML文件可能太危险,在这种情况下,我将限制向管理员上传权限。

    6 回复  |  直到 16 年前
        1
  •  16
  •   wisty    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应该是可以的(去掉脚本标记并不是什么高深的科学)。如果消毒是一个糟糕的循环(或者你只是很谨慎),我想你可以把它放在一个单独的服务器上。

        2
  •  14
  •   Matt McCormick    16 年前

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

    Image.open(filepath)
    

    如果文件不是图像,则会引发异常。我对python/django非常陌生,所以其他人可能有更好的方法来验证图像。

        3
  •  6
  •   brianegge    16 年前

    您要对上传的内容进行的第一件事是将其存储在一个无法直接下载的目录中。如果您的应用程序存在于 ~/www/ 考虑将数据放入“~/data/”。

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

    您不能信任基于扩展名的文件,因此请使用 Fileinfo .然后,为每个mime类型创建一个验证器。ImageMagick可以验证图像文件。为了提高安全性,您可能需要对PDF和Flash文件等文件运行病毒扫描程序。对于HTML,您可能需要考虑限制标记的子集。

    我找不到与 Fileinfo 模块,尽管始终可以执行 /usr/bin/file -i . 大多数允许上传的系统都会创建一个内容名或ID,然后使用mod ou rewrite来解析URL,并在磁盘上找到内容。一旦找到内容,就使用sendfile或类似的方法返回给用户。例如,在内容获得批准之前,可能只允许上载该内容的用户查看该内容。

        4
  •  5
  •   Jiaaro    16 年前

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

    使用nginx而不是apache服务所有用户上传的内容,并将其作为静态内容(即使用户上传,也不会运行任何php或cgi)

        5
  •  2
  •   luc    16 年前

    “可信用户”是一个主观术语。你认识的人是当面认识的还是只认识在你的应用程序上创建了帐户的人?不要让你不认识的人访问你的文件系统。

    无论如何,给别人上传文件的能力有点危险,我认为应该避免。上周我在自动上传HTML代码时遇到了类似的问题,我决定将其存储在数据库中。我认为在大多数情况下,您可以使用数据库而不是文件系统。

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

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

        6
  •  0
  •   Victor Kotseruba    16 年前

    您可以使用验证HTML文件 BeautifulSoup