API安全——SSRF服务端请求伪造的原理以及防范

SSRF全称Server-Side Request Forgery,服务端请求伪造。
在最新的2023 OWASP中API 安全的Top10榜单中,ssrf排第7。

易受攻击原因

我们在开发过程中,通常使用API 获取远程时出现服务器端请求伪造 (SSRF) 缺陷 资源,而不验证用户提供的 URL。它使攻击者能够 强制应用程序将精心编制的请求发送到意外目标, 即使受到防火墙或VPN的保护。

什么是SSRF(服务器端请求伪造)?

SSRF(服务器端请求伪造)是一种安全漏洞,它允许攻击者引诱服务器发起服务器本不打算进行的请求。这种攻击的关键在于,攻击者可以通过服务器发起的请求,访问其无法直接访问的网络资源。

#mermaid-svg-S31f3h6bGxaNaMMY {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-S31f3h6bGxaNaMMY .error-icon{fill:#552222;}#mermaid-svg-S31f3h6bGxaNaMMY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-S31f3h6bGxaNaMMY .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-S31f3h6bGxaNaMMY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-S31f3h6bGxaNaMMY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-S31f3h6bGxaNaMMY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-S31f3h6bGxaNaMMY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-S31f3h6bGxaNaMMY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-S31f3h6bGxaNaMMY .marker.cross{stroke:#333333;}#mermaid-svg-S31f3h6bGxaNaMMY svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-S31f3h6bGxaNaMMY .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-S31f3h6bGxaNaMMY text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-S31f3h6bGxaNaMMY .actor-line{stroke:grey;}#mermaid-svg-S31f3h6bGxaNaMMY .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-S31f3h6bGxaNaMMY .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-S31f3h6bGxaNaMMY #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-S31f3h6bGxaNaMMY .sequenceNumber{fill:white;}#mermaid-svg-S31f3h6bGxaNaMMY #sequencenumber{fill:#333;}#mermaid-svg-S31f3h6bGxaNaMMY #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-S31f3h6bGxaNaMMY .messageText{fill:#333;stroke:#333;}#mermaid-svg-S31f3h6bGxaNaMMY .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-S31f3h6bGxaNaMMY .labelText,#mermaid-svg-S31f3h6bGxaNaMMY .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-S31f3h6bGxaNaMMY .loopText,#mermaid-svg-S31f3h6bGxaNaMMY .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-S31f3h6bGxaNaMMY .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-S31f3h6bGxaNaMMY .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-S31f3h6bGxaNaMMY .noteText,#mermaid-svg-S31f3h6bGxaNaMMY .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-S31f3h6bGxaNaMMY .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-S31f3h6bGxaNaMMY .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-S31f3h6bGxaNaMMY .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-S31f3h6bGxaNaMMY .actorPopupMenu{position:absolute;}#mermaid-svg-S31f3h6bGxaNaMMY .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-S31f3h6bGxaNaMMY .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-S31f3h6bGxaNaMMY .actor-man circle,#mermaid-svg-S31f3h6bGxaNaMMY line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-S31f3h6bGxaNaMMY :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 用户(攻击者) 目标服务器 攻击者服务器 内网资源 发送带有指向攻击者服务器的恶意 URL 的请求 向攻击者的服务器发出请求 响应内部网络资源的 URL 请求内部资源 返回敏感信息 返回敏感信息 用户(攻击者) 目标服务器 攻击者服务器 内网资源

SSRF攻击的工作原理

攻击者通过发送含有特定数据的请求(通常是URL)到服务器,引导服务器访问该URL。这个URL可能指向内部网络中的资源,比如数据库、内部web服务器等。这种攻击手法使攻击者能够绕过防火墙,进入内部网络进行攻击。

攻击场景示例

1、用户头像/图片上传

例如,用户在某个网站上上传个人资料图片。通常情况下,用户可以选择从他们的本地上传图像文件,或者直接提供 URL 图像。这个时候我们假设用户使用图像上传时选择提供url,这个时候会触发以下api:

POST /api/profile/upload_picture
{
  "picture_url": "http://example.com/profile_pic.jpg"
}

这个时候,攻击者可以发送恶意url参数来测试API对应的服务端信息,例如
{ "picture_url": "localhost:8080" }
那么攻击者能够通过响应时间,判断目标端口是否打开,从而进行更深入的渗透操作

2、攻击事件查询

有些团队在开发监控系统时更习惯于直接调取安全产品平台中安全事件的查询接口,例如SIEM类平台的事件接口,假设这里有一个请求,注意看url这个参数

POST /graphql

[
  {
    "variables": {},
    "query": "mutation {
      createNotificationChannel(input: {
        channelName: "ch_piney",
        notificationChannelConfig: {
          customWebhookChannelConfigs: [
            {
              url: "http://www.siem-system.com/create_new_event",
              send_test_req: true
            }
          ]
          }
      }){
        channelId
    }
    }"
  }
]

这个时候攻击者可以利用这个流,修改Url参数使API 请求敏感资源,例如公开凭据的内部云的元数据

POST /graphql

[
  {
    "variables": {},
    "query": "mutation {
      createNotificationChannel(input: {
        channelName: "ch_piney",
        notificationChannelConfig: {
          customWebhookChannelConfigs: [
            {
              url: "http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-default-ssm",
              send_test_req: true
            }
          ]
        }
      }) {
        channelId
      }
    }
  }
]

SSRF的防御策略

以下是一些防御SSRF攻击的建议:

  1. 过滤输入和输出: 对任何用户输入的数据进行严格的验证和过滤,防止恶意输入导致的攻击。

  2. 禁止或限制从服务器发出的请求: 尽可能地减少或禁止服务器向外部发起的请求,限制服务器发起请求的目标范围。

  3. 采用最新的安全漏洞修复: 随着时间的推移,可能会有新的安全漏洞被发现。一旦有新的漏洞被发现,应尽快对其进行修复,防止成为攻击的目标。

  4. 实施网络隔离: 将服务器放置在DMZ区域,从而限制攻击者能够接触的网络资源。

  5. 使用安全库和框架: 使用安全的库和框架可以有效地减少编码错误,从而防止漏洞的产生。

以上就是SSRF攻击的一些基本原理和防御策略。理解并遵守这些策略,可以有效地保护我们的服务器不受SSRF攻击的威胁。