java - Java Websockets 中的来源检查以防止 CSRF

标签 java cross-domain csrf java-websocket tyrus

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

在我看来,要走的路是重写方法:

ServerEndpointConfig.Configurator.checkOrigin(String originHeaderValue)

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

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

我正在考虑在 modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) 的实现中执行此验证,我可以在其中读取所有 header 值,但我很确定我误解了某些内容。

所以我的问题是:

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

谢谢, 纳乔

最佳答案

在深入研究这个问题之后,我得出的结论是,Websocket API (JSR-356) 旨在针对“白名单”执行来源检查,这是一系列预定义的允许来源(如您在 this example 中看到的那样)来自 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 header 验证的可能性。

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

这让我想知道为什么这种类型的检查不优于白名单解决方案,并且刚刚发现了这个有趣的帖子:Origin and Host headers for same domain requests

关于java - Java Websockets 中的来源检查以防止 CSRF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35398798/

相关文章:

java - 从组合框中选择项目时如何从数据库获取 ID 值?

google-chrome - CORS:Firefox 在成功的 OPTIONS 请求后不发送 POST 请求……在 Chrome 中有效

javascript - 服务器端请求和 XmlHTTPRequest(客户端)和安全性

php - 将 token 放在 URL 中是否安全以防止 PHP 应用程序中的 CSRF 攻击?

ruby-on-rails - protected_from_forgery - 顺序重要吗?

java - 使用 Axis2/Java 创建 SSL 客户端

java - com.fasterxml.jackson.core.JsonParseException : Unexpected character(code 160) while reading the json file

java - 无法在 Firefox 上打开默认配置文件

javascript - 确定 iframe 是否在屏幕上可见

java - 使用 OAuth2 SSO 在 spring-boot 应用程序中禁用 CSRF