服务器端请求伪造 (SSRF)

服务器端请求伪造 (SSRF) 是一种漏洞,它允许攻击者向任意目标发起网络请求。SSRF 使这些请求源自服务器本身,而服务器通常比外部客户端拥有更广泛的访问权限。

这可能使攻击者能够访问敏感资源或执行其他未经授权的操作。

示例场景

假设您的应用程序有一个端点,可以从提供的 URL 获取图片。

http
GET /fetch-image?url=https://example.com/image.png

服务器可以访问公司的内网。

如果服务器不对提供的 URL 参数进行验证,那么客户端可以通过将内网 URL 传递给 API 来提取敏感数据。

js
fetch("https://example.org/fetch-image?url=https://:443/admin/org.png");

尽管客户端无法直接访问 https://:443/,但服务器可以,并且服务器会将响应中继给客户端。

客户端不必发起 HTTP 请求:它可能可以使用 file:// 协议。

js
fetch("https://example.org/fetch-image?url=file:///etc/passwd");

在这些情况下,攻击者可以获取对敏感数据的访问权限。有时攻击者无法获得响应正文,但在这种情况下仍然可能造成问题。

  • 通过强制服务器发出大量请求,攻击者可以执行 拒绝服务 (DoS) 攻击。
  • 通过检查服务器返回的状态码或请求的执行时间,攻击者可能会推断出有关目标的敏感信息。

攻击者可能会使用重定向或重定向链来规避验证。例如,他们可能拥有一个域名 https://evilexample.org/redirect,而该主机所做的就是重定向到 https://:443/ 或其他(内部)URL,从而可能绕过输入验证。

js
fetch("https://example.org/fetch-image?url=https://evilexample.org/redirect");

SSRF 的防御措施

缓解 SSRF 漏洞需要多种防御策略,结合输入验证、谨慎的响应处理和安全的网络架构。一些关键方法包括:

输入验证和白名单

限制服务器 API 将使用的 URL。例如,上面讨论的 fetch-image 服务可以指定一个包含预期域名的白名单。

js
const ALLOWED_DOMAINS = ["https://api.example.com", "https://cdn.example.com"];

阻止协议和 URL 方案

确保只允许特定的 URL 方案。对于常规 Web 应用程序,很可能只允许 https:// 就足够了。

重定向验证

不要自动遵循重定向,同时也要对重定向的 URL 执行输入验证和/或白名单。限制重定向链。

最小权限和隔离

确保执行出站请求的服务不拥有超出其所需的任何权限,并避免将具有请求能力的服务器与敏感的内部服务进行共置。

防御总结清单

  • 审查所有获取资源的功能,并验证或白名单用户输入。
  • 阻止除 HTTPS 之外的所有协议。
  • 警惕 URL 重定向并限制重定向链。
  • 对服务器网络权限应用最小权限原则:理想情况下,除非必要,否则服务器不应拥有对内部网络的无限制访问权限。
  • 记录和监控请求。

另见