SSRF 漏洞的原理以及 Java 中的处理
SSRF漏洞的原理
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是由攻击者构造非授权的 URL, 由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。
比如黑客攻击公司内部的论坛, Wiki, 工作流, 项目管理等系统. 大量的内部系统都提供内部匿名的访问方式, 不需要登陆即可以从内网访问到.
当一个服务端的服务, 没有对要请求的 URL做校验, 且用户可以构造这个URL时, 那么攻击者可以利用提供的服务, 直接访问内部系统. 不需要入侵到内网, 即可发起内部调用. 可以获取到内部数据, 或者发起内部的恶意调用. 特别地, 开发人员喜欢在内部系统留一些后门, 可以对数据做变更的操作, 那么这种情况下, 外部的攻击者就可以直接触发这些调用.
有漏洞的 Java 代码示例
public String getContentWithVul(String url) {
return HttpUtils.URLConnection(url);
}
你可能会问, 这么简单的一行代码, 为什么会有漏洞呢?
这段服务端的 Java 代码请求了一个 url , 返回url 的内容. 代码没有对 URL进行校验. 如果这是一段爬虫代码, 用来爬取外部的 URL. 那么当采集到的 url 是内部URL 的时候, 爬虫服务器会触发内部的 url 调用. 引起内部信息泄漏, 内部系统被恶意调用, 篡改数据等严重问题.
Java 中如何避免 SSRF
只需要在服务端对要发起请求的 URL 做判断即可. 检测 URL 是内部的域名, 或者 IP 地址, 就进行拦截.
有时候我们需要调用的内部其它服务, 这种情况下把内部的 域名, IP 添加白名单即可.
防 SSRF 攻击的代码调用示例:
public String httpURLConnection(@RequestParam String url) {
try {
### 请求 URL 前, 启动 hook, hook 会对请求的 url 做检查
SecurityUtil.startSSRFHook();
return HttpUtils.HTTPURLConnection(url);
} catch (SSRFException | IOException e) {
return e.getMessage();
} finally {
SecurityUtil.stopSSRFHook();
}
}
开源项目
可以使用 java-sec-code 中的类库来做 SSRF 的处理.
https://github.com/JoyChou93/java-sec-code
https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SSRF.java