【问题标题】:Fetching a file on a server, resizing with PHP GD2, security considerations在服务器上获取文件,使用 PHP GD2 调整大小,安全注意事项
【发布时间】:2012-01-26 06:37:38
【问题描述】:

服务器从不受信任的域中获取文件时有哪些安全注意事项?

使用 PHPs GD2 库调整您不信任的图像大小时有哪些安全注意事项?

该文件将存储在服务器计算机上,并可供下载。我知道我不能信任 MIME-Type 标头。还有什么需要注意的吗?


我有一个如下所示的webservice

输入

一个 http-URL(或一个 String 应该是一个 URL)

输出

文件的元描述,如果有则错误。

元描述有两种形式之一:

  1. 这是一张图片 + 我的域中图片的 URL + 图片的缩略图(在我的服务器上生成并托管)
  2. 这不是图像 + 指向我域中文件的 URL

更新

我可以提出的问题:

  1. 远程服务器是一个恶意服务器,它会发送微小的信息,足以让套接字保持打开状态,但不会做任何有用的事情——比如slowloris。我不知道这是多么真实的威胁。我想通过超时+进度检查可以很容易地避免它。

  2. 远程服务器提供一些看起来像图像(标题,mime 类型)的东西,但是当我用 GD2 加载它时会导致 PHP 崩溃。

  3. 服务器发送一个无用或错误的 MIME 类型标头。就像text-plain 用于二进制文件一样。

  4. 远程服务器提供包含病毒的图像。我认为调整图像大小会摆脱病毒,但如果没有理由缩放,我将提供原始图像。

  5. 远程服务器提供包含病毒的文件。该文件不会被视为图像,因此我的服务器不会对其执行任何操作。在用户下载并运行它之前,什么都不会发生。

另外,我假设我可以信任我的服务的用户。这是一个私人应用程序,在这种情况下用户可能会对不良行为负责。我认为他们不会故意尝试破坏它。

【问题讨论】:

  • 你能告诉我更多关于你指的是什么类型的安全问题吗?因为就下载文件和镜像它而言,您可以强制下载托管在服务器上的文件以防止它们运行,因此除了可能存在病毒并被谷歌阻止之外,不会有任何问题。就图像而言,调整它们的大小应该没问题,就我而言,如果文件不是有效的图像,它将不会调整大小,所以你不应该有任何问题。
  • 我不打算运行我的服务器上的文件。这不应该发生,除非 PHP 函数中存在错误(这是一个有效的问题)。如果文件包含病毒,我几乎无法保护用户。我想保证我的服务器是安全的。

标签: php security gd


【解决方案1】:

服务器从不受信任的域中获取文件时有哪些安全注意事项?

域(主机)和文件不可信。这涉及两点:

  1. 交通
  2. 数据

要安全地传输数据,请使用超时和大小限制。现代 HTTP 客户端库提供了这两者。如果无法及时请求文件,请断开连接。如果文件太大,请删除数据。告诉用户获取文件时出现问题。或者,让用户通过使用用户浏览器和 javascript 来获取文件来处理到该服务器的传输。然后发布它。使用您的脚本设置发布限制。

只要数据不受信任,您就需要谨慎处理。这意味着,您自己实现了一个进程,该进程能够在将文件标记为“安全”之前对文件运行不同的安全检查。

使用 PHPs GD2 库调整您不信任的图像大小时有哪些安全注意事项?

然后不要将不受信任的数据传递给图像库。看上面的步骤,先让它进入安全状态。

该文件将存储在服务器计算机上,并可供下载。我知道我不能信任 MIME-Type 标头。还有什么需要注意的吗?

我认为您仍然处于上述观点。如何从 untrustedsafe。当然你不能相信 Content-Type 标头,但是理解它也很好。

您想防止Unrestricted File Upload Vulnerability­OWASP

  1. 检查文件名。如果您将数据存储在您的服务器上,请为其指定一个安全的临时名称,该名称不能预先猜到并且无法通过网络访问。
  2. 检查与文件名关联的数据,例如该文件源的 URL 信息。正确处理编码。
  3. 丢弃任何不符合您期望的东西,因此请严格检查您制定的先决条件。
  4. 在继续之前验证文件数据,例如使用病毒检查程序。
  5. 在继续之前验证图像数据。这包括文件头(幻数)以及文件大小和文件内容是否有效。您应该使用专门用于该工作的库,例如图像文件格式畸形检查器。这是专门的软件,所以如果您的这部分业务开展业务。存在许多免费软件图像文件代码,我将其留作参考,无论如何您都不能相信任何建议,需要进入主题。
  6. 如果您打算自己调整图像大小,则需要确保所有内容都具有双重安全性,因为您计划在托管之后处理数据。因此,首先要了解如何处理数据以定位潜在的问题领域。
  7. 进行日志记录和监控。
  8. 为万一出现问题制定计划。
  9. 考虑对已经存在的文件重复该过程,因此如果您更改过程,您可以自动将这些原则应用于过去完成的上传。
  10. 为完成工作后能够清理的每种工作类型创建一个系统。一个系统进行下载,一个系统获取元数据等。每次操作后,从映像恢复系统。如果单个组件发生故障,它不会处于被利用状态。此外,如果您检测到故障,您可以让整个系统停止工作,直到发现缺陷为止。

所有这一切都取决于你想要做多少,但我想你明白了。创建一个适合您的流程,让您知道可以在哪些方面进行改进,但首先要创建一个足够模块化以处理错误情况的基础架构,并且它可能封装了足以处理任何结果的流程。

您可以将关键部分委托给您不需要关心的系统,例如将处理与托管分开。此外,当您托管图像时,网络服务器一定不聪明。一个系统越愚蠢,它的可利用性就越低(通常)。

如果托管不是您业务的一部分,为什么不将其交给 amazon s3 或类似商店呢?可以通过 DNS 设置保留您的域。

保持您用来验证图像的库是最新的(这意味着您知道使用了哪些库及其版本,例如 PHP exif 扩展正在使用 mbstring 等。pp. - 跟踪整个树)。请注意,您可以以有用的方式向库维护者报告缺陷,例如具有日志记录、存储上传数据以重现内容等。

了解过去确实存在哪些图像漏洞以及哪些系统/组件/库 (example, see disclaimer there) 受到影响。

也进入主题,这是利用某些东西的常用方法,将基础知识放在一起(我相信你知道,但是重新阅读一些东西总是好的):

一些相关的问题,分类:

【讨论】:

    【解决方案2】:

    您所描述的基本上归结为输入验证问题;你不相信你的应用程序正在读取什么作为输入和处理。

    要解决这个问题,您应该下载相关资源,然后尝试确定真正的文件类型。有多种方法可以尝试此操作,但基本上您将希望使用一些自定义代码或库来解析文件并查找某种类型的标记。这里有一个关于如何在 PHP 中执行此操作的很好的讨论 - How can I determine a file's true extension/type programatically? - 我会检查第二个答案,其中列出了一些特定于 PHP 的函数来执行此操作。当你的应用程序接收到一个文件时,它应该像这样执行一些真正的文件类型,然后将结果与来自远程服务器的指定 MIME 类型进行比较;如果匹配则接受该文件,如果不匹配,则删除它。

    我还建议使用允许文件类型的白名单(您的服务将支持的所有内容的列表,然后只接受这些类型的文件)。如果您有一个非常通用的服务,那么您至少应该创建一个不允许的文件类型的黑名单(您的服务绝对不支持的所有内容的列表,并根据您的 MIME 类型比较的结果立即删除这些文件类型)。同样,这些的使用完全取决于您的用例。

    一旦你有了一个类型,你就会担心远程服务器发送给你的是一个针对你的服务器的错误文件(包含恶意代码,旨在使 GD2 库崩溃并运行任意代码的缓冲区溢出,等等)。基本上,您依赖 GD2 库不包含会导致如此成功的漏洞利用的错误。除了自己对库运行安全审计之外,您在这里无能为力,我假设这超出了范围。基本上,尽快跟进库中报告的任何安全漏洞并打补丁;作为图书馆的消费者,您确实依赖维护者来查找和修复此类安全漏洞。

    接下来,需要担心的是远程服务器向您发送了一个针对您的用户/客户端的错误文件(包含恶意代码、缓冲区溢出、病毒等)。在这里,如果图像中存在真正是恶意软件的损坏数据,则很可能 (1) 在读取 GD2 时破坏或利用 GD2(该场景见上文)或 (2) 在执行调整大小操作时被消除如果 GD2 可以成功处理它,则由库提供。尽管进行了处理,但仍有可能保留它,但您也无能为力。如果您真的对此感到担忧,您可以使用专为此设计的外部产品应用病毒扫描;我建议如果您这样做,那么(1)在下载之后和 GD2 处理之前,然后(2)在您提供之前处理过的文件。就个人而言,我认为这样做不会有什么好处,但如果你想为你的用户提供额外的检查/温暖的模糊,它不会受到伤害。

    为了解决数据传输缓慢以保持连接打开的问题,请在任何连接上设置超时以处理此问题;除非您在这里处理对您的用例的特定威胁,否则我认为这不是一个大问题。

    【讨论】:

    • PHP 函数似乎也使用幻数方法来检测实际的 MIME 类型。它比扩展嗅探要好得多,但它不能保证。我不能使用白名单,因为很可能会使用一些我不知道的专有文件类型。是否绝对需要有黑名单?我可以看到 HTML 文件(包含会话窃取程序)的一些问题。可以以某种方式绕过吗?
    • 大多数真实归档类型确实使用幻数和/或标题结构验证。真的没有更好/更强大的方法来做到这一点。这就是为什么我建议将您获得的内容与提供的 MIME 类型(健全性检查)进行比较。那时,您真的依赖解码库(用于图像的 GD2、用于 HTML 文件的 HTML 解析器等)不会在格式错误的文件上破坏/被利用。至于白名单/黑名单,您也可以选择清理为反对接受/拒绝;使用 OWASP 等经过测试/可靠的库对所有 HTML 文件(其他类似)进行 HTML 编码,以使它们更安全。
    【解决方案3】:

    1) 对于从不受信任的域中盲目地获取文件,我主要关心的是如何验证该文件实际上是您期望获得的文件。不受信任的服务器是否会欺骗您的脚本下载有害文件(如病毒)或可能允许后门进入您系统的脚本?

    2) 我没有读到任何关于使用 GD2 库调整图像大小的安全问题。如果一开始不是图像,GD2 函数会抛出错误。我认为这部分您不必担心太多。

    3) 如果不检查我的脚本首先下载的每个文件,我(个人)永远不会这样做。如果您想部分自动化,您可以考虑对所有文件运行magic number 测试作为预过滤器。但人类的外观是提供随机文件的最安全方式。当你完成这个项目时——在你让它上线之前——尽可能努力地破坏/欺骗/破解它。找一些知识渊博的朋友帮忙。

    【讨论】:

    • 1.我认为这只有在我 run 文件时才会发生。 3. 幻数检查是明智的检查,但不能保证。如果存在真正的恶意意图,则很容易绕过。
    • 1) 如果您将文件提供给其他人,那么您的服务器可以运行它。 3) 这就是我的观点:如果没有受信任的某人进行某种人工审查,则无法保证的。我知道你说过你对用户有默认信任,但只需要被烧一次就会真正伤害到你。
    • 1) 我想我只是在使用readfile 或者echo file_get_contents()。该文件是如何运行的? 3) 我唯一关心的是服务器——我并不严格关心文件是否包含可能会扰乱用户 PC 的病毒。 PICNIC 错误超出范围 ;)
    • 1) 不是 - 但你最初并没有说你是这样做的。 =) 我假设您将其留给 Web 服务器自己提供文件,而不是让脚本显示原始内容。 3) 如果您按照刚才解释的方式阅读文件,并将抓取的文件存储在网络不可访问的路径中,那么您应该是非常安全的。
    【解决方案4】:

    当它不是图像时,无论哪种文件,您都以任何方式存储文件?这样他们就可以上传和 php 文件并浏览到它以在您的服务器上执行 php 代码?

    【讨论】:

    • 这不是发布问题的部分,您需要在此处发布答案或使用问题的评论部分
    • 我在哪里评论第一个问题?
    • 我评论的地方,但我认为你没有足够的声誉,因此你还不能发表评论。
    • 是的,我会接受任何文件。当然,我可以选择将已知的 problematic 文件类型(例如 .js .php .exe)列入黑名单,但理想情况下我不必这样做。这当然是可能的,因为我相信系统的用户没有恶意。
    • 所以如果我想回答这个问题但需要更多关于你的信息是不可能的?
    猜你喜欢
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多