【问题标题】:Django prevent image upload containing possible XSS codeDjango 阻止包含可能 XSS 代码的图像上传
【发布时间】:2020-08-06 23:02:24
【问题描述】:

我正在创建一个用户可以上传图片的网站。我正在使用django-storages 将这些图像转发到 S3 存储桶,但我最近阅读了 Django 网站上的安全文档:https://docs.djangoproject.com/en/3.0/topics/security/#user-uploaded-content

当以不遵循安全最佳实践的方式提供媒体时,Django 的媒体上传处理会带来一些漏洞。具体来说,如果 HTML 文件包含有效的 PNG 标头和恶意 HTML,则该文件可以作为图像上传。该文件将通过 Django 用于 ImageField 图像处理 (Pillow) 的库的验证。当此文件随后显示给用户时,它可能会显示为 HTML,具体取决于您的 Web 服务器的类型和配置。

它告诉我有关此漏洞的信息,但它没有为我提供防止这些漏洞的有效方法。这是网站中第三大最易受攻击的攻击。

考虑从云服务或 CDN 提供静态文件以避免其中一些问题。

我正在使用 S3 来提供我的媒体文件,它确实说要避免本节中描述的一些漏洞,但没有说 哪个

我的问题:向 AWS S3 上传和提供图像是否容易受到这些攻击,如果没有,什么是有效的方法清理图像的内容?

为赏金编辑:我将图像托管在 S3 上,可能会发生哪些类型的攻击或漏洞?以及如何防止此类攻击?

【问题讨论】:

  • 拥有单独的域名(即使它们托管在同一台服务器上)和主域的 CORS 策略应该可以防止大多数攻击。您还可以考虑在存储之前使用 PIL/Pillow 对上传的 PNG(和其他图像)文件进行重新编码,以确保它们是合法的图像文件。
  • @Selcuk 从 S3 提供的图像是否受到 CORS 策略的限制?它本身是从与我的域不同的s3.amazon.x 提供的。
  • 同源策略应该由你的主域名执行,而不是s3。使用 s3(或任何其他域名)只是让您的 Web 服务器区分来自主域名和来自媒体文件的请求。请参阅django-cors-headers 了解 Django 特定实现。
  • @Selcuk 我确实设置了 cors 设置,因为我使用的是 Django REST,是我需要处理的 CORS_ORIGIN_WHITELIST 吗?还是我需要做其他事情来防止此类攻击?
  • 很难保证某些东西可以抵御各种攻击,但这是一个好的开始。欢迎来到信息安全。

标签: django amazon-s3


【解决方案1】:

为什么不直接验证文件是否为有效图像?:

from PIL import Image
image = Image.open(file)
image.verify()

正如另一位发帖人所建议的那样,您确实可以尝试转换并检查是否引发异常,但 verify() 可能会更快。

或者你可以尝试检测类型?:

import imghdr
path = 'Image.jpg'
imghdr.what(path)

或者

from PIL import Image
image = Image.open('myimage.png')
image.format

使用上述任何一种方法,您都可以确定文件是否实际上是图像。如果它不是图像,则认为该文件是虚假文件,并且不要将其输出到您的任何网页上。通过不输出文件,不会有来自此向量的 XSS 风险,因为即使文件是 HTML,通过不将其输出到您的页面上,它也不会危及您的页面。

【讨论】:

  • Afaik,他们可以通过伪造标题绕过检测,或者那样不行?
  • 那么 Django docs 的确切含义是“具体来说,如果 HTML 文件包含有效的 PNG 标头后跟恶意 HTML,则该文件可以作为图像上传。该文件将通过库的验证Django 用于 ImageField 图像处理(Pillow)。”
  • @Paaksing 仅指上传文件。仅仅因为文件具有 png 标头或扩展名并不意味着它实际上是 png 文件。我的答案中的代码不使用标题 - 它查看实际文件,因此标题应该是无关紧要的。试试看。
  • 使用上面的代码可以验证文件是否为图片文件。如果不是,则不要在您的页面上输出它 - 如果您不输出它,那么您不会冒 xss 的风险。
  • 或者更准确地说,你不会从这个向量中冒 XSS 的风险。
【解决方案2】:

最好的解决方案来自Pillow library 本身。

即使有人可以操纵 HTML 文件的标题以使它们看起来像 PNG 文件,但当您尝试对它们进行一些操作(例如 resizing)时,它根本无法工作并引发错误,因此您可以在 try except 块中捕获它并警告/标记用户是否有恶意。

如果您不想降低给您的任何图像的质量,那么您可以调整到原始图像大小,它会在不影响图像质量的情况下工作。

【讨论】:

  • 目前我正在使用easy_thumbnails对图像进行自动裁剪,在查看了它的依赖关系后,它使用了 Pillow,你认为从那里信任它可以吗?
  • @Paaksing 是的,我认为它应该是安全的,但只是为了安全,你为什么不试试看自己呢。但我几乎 100% 确定它是安全的。希望答案有帮助,如果有帮助,请点赞。感觉很好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 2012-05-19
  • 2012-05-18
  • 2019-03-13
  • 1970-01-01
相关资源
最近更新 更多