SSRF代码审计和防御策略 for Java
langu_xyz

1、Java代码中的SSRF触发点

SSRF的产生需要满足两个点:1. 接收外部传入的地址,2.发送请求。

URL
HttpClient
HttpURLConnection
ImageIO
DriverManager
Socket
OkHttpClient
……

2、如何防御SSRF攻击

2.1 白名单判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class SSRFWhiteChecker extends WhiteChecker {
private static SSRFWhiteChecker instance = null;

public SSRFWhiteChecker(){

}

public static SSRFWhiteChecker getInstance() {
if (null == instance) {
synchronized (SSRFWhiteChecker.class) {
if (null == instance) {
instance = new SSRFWhiteChecker();
}
}
}
return instance;
}

/**
* @Description: 校验url是否在白名单内
* @Param: url 网络地址
* @return: boolean true 在白名单内;false 不在白名单内
*/
public boolean verifyURL(String url){
return super.verifyURL(url);
}
}

2.2 防止重定向绕过

对每次跳转都进行判断

2.3 利用NetHooks实现TCP请求前置判断

通过sun.net.NetHooks实现拦截TCP请求,进行host判断。

该类的方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
* 定义要在绑定或连接TCP套接字之前调用的静态方法。
*/

public final class NetHooks {

/**
* 带钩子的提供者,允许在绑定或连接TCP套接字之前转换套接字。
*
* <p> 这个类的具体实现应该定义一个零参数构造函数,并实现下面指定的抽象方法。
*/
public static abstract class Provider {
/**
*初始化该类的新实例。
*/
protected Provider() {}

/**
*在绑定TCP套接字之前调用。
*/
public abstract void implBeforeTcpBind(FileDescriptor fdObj,
InetAddress address,
int port)
throws IOException;

/**
*在连接未绑定的TCP套接字之前调用。
*/
public abstract void implBeforeTcpConnect(FileDescriptor fdObj,
InetAddress address,
int port)
throws IOException;
}

/**
* 现在,我们在Solaris上加载SDP provider。将来,这可能会被更改为使用ServiceLoader工具,以允许部署其他提供者。
*/
private static final Provider provider = new sun.net.sdp.SdpProvider();

/**
* 在绑定TCP套接字之前调用。
*/
public static void beforeTcpBind(FileDescriptor fdObj,
InetAddress address,
int port)
throws IOException
{
provider.implBeforeTcpBind(fdObj, address, port);
}

/**
* 在连接未绑定的TCP套接字之前调用。
*/
public static void beforeTcpConnect(FileDescriptor fdObj,
InetAddress address,
int port)
throws IOException
{
provider.implBeforeTcpConnect(fdObj, address, port);
}
}

  • Post title:SSRF代码审计和防御策略 for Java
  • Post author:langu_xyz
  • Create time:2018-05-15 21:00:00
  • Post link:https://blog.langu.xyz/SSRF代码审计和防御策略 for Java/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.