来源检查 Java Websockets 以防止 CSRF
Origin check in Java Websockets to prevent CSRF
我正在以编程方式部署一个 Java Websocket 端点 (JSR356 3.1),我希望它验证 Origin
请求 header 值以减轻 CSRF 攻击,并且只接受Host
和 Origin
header 值匹配的握手请求。
在我看来,要走的路是重写方法:
ServerEndpointConfig.Configurator.checkOrigin(String originHeaderValue)
(Tomcat 8 always returns true
)提供的实现,但是我看到的问题是这个方法只有一个参数,我错过了宿主header 与此值进行比较的值。
此外,此 class 不提供任何返回此信息的方法,因此我认为此方法无用,除非您将原始 header 值与先前已知的主机值或集合进行比较值,但这也没有任何意义,因为我的应用程序可以在不同的、不断变化的主机名或 IP 下看到。
我正在考虑在 modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)
的实现中执行此验证,我可以在其中读取所有 header 值,但我很确定我误解了什么。
所以我的问题是:
执行此验证的正确方法是什么?
谢谢,
纳乔
在深入研究问题后,我得出结论,Websocket API (JSR-356) 旨在针对 "white list" 一系列预定义的允许来源执行来源检查(正如您在 Weblogic 的 this example 中看到的那样):
...
import javax.websocket.server.ServerEndpointConfig;
public class MyConfigurator extends ServerEndpointConfig.Configurator {
...
private static final String ORIGIN = "http://www.example.com:7001";
@Override
public boolean checkOrigin(String originHeaderValue) {
return ORIGIN.equals(originHeaderValue)
}
}
...
但不幸的是,此 API 并未考虑实施 Host
与 Origin
header 验证的可能性。
作为解决方法,对于那些将 websocket 端点放在 servlet 堆栈后面的服务提供商(如 Tomcat,其中 Websocket 机制由 servlet 过滤器 org.apache.tomcat.websocket.server.WsFilter
触发),您可以创建一个启用线程本地访问请求的外部过滤器,以便在 checkOrigin()
方法中使用它来获取 Host
header 值。
这让我想知道为什么这种类型的检查不比白名单解决方案更受欢迎,并且刚刚发现这个有趣 post:Origin and Host headers for same domain requests
我正在以编程方式部署一个 Java Websocket 端点 (JSR356 3.1),我希望它验证 Origin
请求 header 值以减轻 CSRF 攻击,并且只接受Host
和 Origin
header 值匹配的握手请求。
在我看来,要走的路是重写方法:
ServerEndpointConfig.Configurator.checkOrigin(String originHeaderValue)
(Tomcat 8 always returns true
)提供的实现,但是我看到的问题是这个方法只有一个参数,我错过了宿主header 与此值进行比较的值。
此外,此 class 不提供任何返回此信息的方法,因此我认为此方法无用,除非您将原始 header 值与先前已知的主机值或集合进行比较值,但这也没有任何意义,因为我的应用程序可以在不同的、不断变化的主机名或 IP 下看到。
我正在考虑在 modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)
的实现中执行此验证,我可以在其中读取所有 header 值,但我很确定我误解了什么。
所以我的问题是:
执行此验证的正确方法是什么?
谢谢, 纳乔
在深入研究问题后,我得出结论,Websocket API (JSR-356) 旨在针对 "white list" 一系列预定义的允许来源执行来源检查(正如您在 Weblogic 的 this example 中看到的那样):
...
import javax.websocket.server.ServerEndpointConfig;
public class MyConfigurator extends ServerEndpointConfig.Configurator {
...
private static final String ORIGIN = "http://www.example.com:7001";
@Override
public boolean checkOrigin(String originHeaderValue) {
return ORIGIN.equals(originHeaderValue)
}
}
...
但不幸的是,此 API 并未考虑实施 Host
与 Origin
header 验证的可能性。
作为解决方法,对于那些将 websocket 端点放在 servlet 堆栈后面的服务提供商(如 Tomcat,其中 Websocket 机制由 servlet 过滤器 org.apache.tomcat.websocket.server.WsFilter
触发),您可以创建一个启用线程本地访问请求的外部过滤器,以便在 checkOrigin()
方法中使用它来获取 Host
header 值。
这让我想知道为什么这种类型的检查不比白名单解决方案更受欢迎,并且刚刚发现这个有趣 post:Origin and Host headers for same domain requests