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); } }
|