Java Websockets 中的源码检查以防止 CSRF



我正在以编程方式部署一个Java Websocket端点(JSR356 3.1(,我希望它验证Origin请求头值以减轻CSRF攻击,并且只接受HostOrigin头值匹配的握手请求。

在我看来,要走的路是覆盖方法:

ServerEndpointConfig.Configurator.checkOrigin(String originHeaderValue)

(Tomcat 8 提供的实现总是返回 true (,但我看到的问题是此方法只有一个参数,并且我错过了与此值进行比较的主机标头值。

此外,此类不提供任何返回此信息的方法,因此我认为此方法毫无用处,除非您将 origin 标头值与以前已知的主机值或一组值进行比较,但这也没有任何意义,因为我的应用程序可以在不同的、不断变化的主机名或 IP 下看到。

我正在考虑在modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)的实现中执行此验证,我可以读取所有标头值,但我很确定我误解了什么。

所以我的问题是:

执行此验证的正确方法是什么?

谢谢纳乔

在深入研究

了这个问题之后,我得出结论,Websocket API(JSR-356(旨在针对"白名单"执行源检查,白名单是一系列预定义的允许源(如Weblogic的此示例所示(:

 ...
 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 没有考虑实现 HostOrigin 标头验证的可能性。

作为一种解决方法,对于那些将 websocket 端点放在 servlet 堆栈后面的服务提供者(如 Tomcat,其中 Websocket 机制由 servlet 过滤器org.apache.tomcat.websocket.server.WsFilter触发(,您可以创建一个外部过滤器,使 threadlocal 能够访问请求,以便在 checkOrigin() 方法中使用它来获取Host标头值。

这让我想知道为什么这种类型的检查不优于白名单解决方案,并且刚刚发现了这个有趣的帖子: 相同域请求的源和主机标头

相关内容

  • 没有找到相关文章

最新更新