3

问题:如果我有一个不受信任的、用户提供的文件 URL,当我下载该文件时如何保护自己免受服务器端请求伪造?.NET Framework (4.8) 基类库中是否有工具可以帮助我,或者是否有一些针对此用例的规范参考实现?


详细信息:我们的网络应用程序(在线产品数据库)允许用户上传产品图片。我们要求应允许用户提供(自托管)图像的 URL,而不是上传图像。

到目前为止,一切都很好。但是,有时我们的 Web 应用程序必须从(外部、用户提供的)URL 中获取图像才能对其进行处理(例如,将图像包含在 PDF 产品数据表中)。

这使我的 Web 应用程序面临Server-Side Request Forgery的风险。OWASP 备忘单将此用例记录为“案例 2”,并提出了一些缓解措施,例如验证 URL 和将已知的内部 IP 地址列入备份列表。

这意味着我不能使用内置方法来下载文件,例如WebClientor HttpWebRequest,因为这些类负责 DNS 解析,并且我需要在 DNS 解析之后执行 HTTP 请求之前验证 IP 地址。我可以自己执行 DNS 解析,然后使用(经过验证的)IP 地址和自定义 Host 标头创建一个 Web 请求,但这可能会弄乱 TLS 证书检查。

长话短说,我觉得我在这里重新发明了轮子,因为这听起来像是一个足够常见的用例。(我肯定不是第一个必须从用户提供的 URL 获取文件的 Web 开发人员。) .NET Framework 具有防止内置 CSRF 的工具,所以我想知道我是否有类似的工具可用于 SSRF只是还没找到。


标签中有类似的问题(例如这个),但是,与它们相反,我的目标不是“摆脱警告”,而是真正保护我的系统免受 SSRF。

4

1 回答 1

1
  1. 与业务利益相关者确认需求。他们很可能并不关心文件是如何获得的——他们只是希望用户能够指定一个 URL 而不是本地文件。如果是这种情况,您的应用程序可以使用 Javascript从浏览器下载文件,然后从那里上传。这完全避免了服务器端的问题。

  2. 如果您必须在服务器端进行,请询问专用服务器的预算。在 DMZ 中找到它(在外围防火墙和将 Web 服务器与网络其余部分隔离的防火墙之间)。使用此服务器运行一个程序,该程序下载 URL 并将数据放在您的主应用程序可以获取的位置,例如数据库。

  3. 如果您必须在现有硬件上托管它,请使用专用进程,在具有专用用户身份的专用应用程序池中运行。此服务的正确位置是在您的 Web 服务器(而不是应用程序或数据库服务器)上。

  4. 审核和监控专用用户的安全日志。

  5. 撤销对私钥或本地资源(如文件系统)的任何权限。

  6. 验证协议(仅限 http 或 https)。

  7. 尽可能验证 IP 地址,并维护黑名单。

  8. 验证域名以确保它是公共 URL,而不是您网络中的内容。如果可能,请使用具有公共 DNS 的代理服务器。

于 2020-12-16T18:40:06.220 回答