存储和重放用户提供的 mime 类型是否安全?

信息安全 Web应用程序 上传文件 文件类型
2021-09-05 18:40:01

如果用户上传文件但通过将 mime-type 设置为任意值(如“superdangerous/blackhatstuff”)来修改请求,我以后将相同的 mime 类型发送回不同的用户是否安全?

即另一个用户下载相同的文件,我将 mimetype 设置为“superdangerous/blackhatstuff”,是否可以将 mime 类型设置为潜在危险的东西?因为它是用户提供的数据,我觉得在没有某种清理的情况下存储和重放不是一个好主意。(当然,我会在存储 mime 类型之前对查询进行清理,所以我不关心通过 mime 类型进行的 SQL 注入攻击。)

我正在使用 clam AV 扫描上传的文件,希望能捕捉到一些 mime 嗅探攻击,但这并不是我在这里真正要问的。

如果这实际上是危险的,那么正确的做法是什么?我应该根本不指定 mime 类型,让接收者猜测吗?我是否应该尝试做自己的 mime 嗅探(我在 Linux 上使用 PHP,它提供了一个用于文件魔术的 API。)

编辑:更多细节

让我解释一下这个功能的目的。有问题的应用程序用作需要提交各种工件以供审查和批准的工作流的一部分,包括(但不限于)word 文档、电子表格、图像和档案。其他用户需要能够下载这些工件才能查看它们并做出批准决定。

为防止出现一些明显的违规行为,我们设置了黑名单(例如上传 PHP 或 Javascript 文件),并且我们将 Content-Disposition 设置为“附件;文件名=...”。我们在上传的文件上运行 Clam AV 作为基本清理,因为我们不能真正对我们的用户强制执行白名单。该应用程序在 Intranet 上运行,需要在访问任何内容之前进行身份验证,并且我们的用户 [大部分] 受到信任。

无论如何,重点是我不是在询问存储文件和让用户下载这些文件的安全性。(我意识到这是一个很大的威胁向量,但这不是我要问的问题。)我真的更关心重播用户提供的 mime 类型是否安全,如果不是,还有什么替代方案?根本不指定 MIME 类型?

4个回答

不,您不应将用户提供的 MIME 类型回复给用户。您向用户公开的最简单的攻击是使用任意 Javascript 代码(例如在 [script] 元素中)上传文本/html 文件。给定上传文件 URL 的用户将执行 Javascript,从而导致XSS通过使用 Content-Type-Disposition: 附件标头提供文件可以在一定程度上缓解这种情况,但有一些方法可以解决这个问题。

另一个向量是存储恶意 Java 小程序或 Flash 文件以及许多其他文件,这些文件的 MIME 类型使它们与网络安全相关(HTML5 脱机清单文件、crossdomain.xml、客户端上可执行的各种文件 - exe、vbs ......)。

虽然我们正在这样做 - 请务必从与您的“主要”应用程序分开的域中提供用户提供的文件,以防止 XSS 攻击(如果文件来自不同的域,同源策略将阻止它们)。

简短的回答:这不安全。允许用户指定 MIME 类型和文件内容是自找的 XSS 漏洞。

恶意用户 Mallory 可以指定 MIME 类型 text/html,并提供包含恶意 Javascript 的 HTML 文档。当您将该文档提供给另一个用户 Alice 时,Alice 的浏览器将执行恶意 Javascript。恶意 Javascript 可以窃取 Alice 的会话 cookie、此站点的 Alice 密码以及 Alice 在此站点上的所有数据,或者可以篡改 Alice 在此站点上看到的内容。

所以,不,这不安全。

编辑(11/4): 我看到你编辑了你的问题,问你应该做什么。这是一个复杂的问题,但让我给你一些基本的策略来抵御这种威胁:

  • 选项 1:没有用户提供的内容。不要托管用户提供的内容。那么你就不用担心这个问题了。

  • 选项 2:仅允许列入白名单的 MIME 类型。允许用户上传数据并指定 MIME 类型,但前提是用户提供的 MIME 类型位于无法触发执行恶意代码的已知安全 MIME 类型的白名单中。例如,如果您对内容嗅探攻击应用适当的防御措施text/plainimage/jpeg通常是安全的,因此可以包含在白名单中。 并且不安全,不应包含在白名单中。text/htmlapplication/x-shockwave-flash

  • 选项 3:使用不同的域。提供来自不同域的用户上传的内容。确保该域仅托管用户提交的非安全敏感内容。不要在该网站上托管您自己的任何材料。然后,浏览器的同源策略将隔离攻击:恶意上传的文件可能能够攻击该域上其他用户上传的内容,但不能窃取密码/会话 cookie/等。从您的主站点。

我以后将相同的 mime 类型发回给不同的用户是否安全?

我会碰碰运气说是的,但如果没有成功,你可能不得不停下来。

在这种情况下,具有大部分受信任用户、白名单或限制上传 MIME 类型的封闭环境将为您的一定比例的用户群增加一点开销或效率低下。用户越多,他们就越有可能使用一些您没有考虑过的格式。如果用户的文件格式不在您的列表中,那么您要么必须破例,修改您的白名单,要么他们需要将文件转换为不同的格式。它的工作,它有成本。

您已经考虑过这个问题,并通过防病毒扫描提供了一些缓解措施。这种缓解是不够的。您需要确保备份您的机器,如果机器因任何原因出现故障,您需要及时恢复丢失的服务。此外,您需要监控用户正在使用 MIME 类型做什么,如果它被滥用或成为问题,那么您需要打开白名单。

这基本上归结为您为用户提供他们需要的东西,并在必要时保护他们免受彼此和他们自己的伤害。根据您的用户是谁,您甚至可能想指出问题并让他们知道您将观看。类似于:“大家好,新的审核服务器在 192.168.0.240。您可以提交任何您想要的文件格式,这有点冒险,但我会记录并审核上传的内容。”

好吧,从用户那里返回未修改的内容类型最终可能会导致您在“第三帝国规则/heil-hitler”类型下发送内容,这可能会让您在某些圈子中被起诉和/或嘲笑低/奇怪的幽默感(例如位于北大西洋和北太平洋之间的一半土地)。

如果你想发回一个用户指定的内容类型,那是因为你实际上想把一个由另一个用户上传的文件发回给用户——这已经是一大堆蠕虫了。我所说的“罐头”是指“20 加仑罐”。

您可以用电子邮件服务器经常这样做的想法来安慰自己:每封电子邮件可能都带有许多电子邮件服务器不知道的内容类型的附件。从历史上看,这暗示了邮件代理的大量安全问题,当收到标记为“可执行”的文件时,发现它适合做出反应:“可执行文件?太好了,让我们自动运行它!”。

如果您的律师不让您走非我的错的道路,那么您将需要彻底清理文件内容,这必然意味着知道文件类型,这自然意味着知道什么内容类型是合适的。所以让用户指定的内容类型通过的问题不应该是相关的。如果是这样,那么你的卫生过程中有一些可疑的东西。