我正在编程地部署一个Java端点(JSR356 3.1),我希望它验证Origin请求头值,以减少CSRF攻击,并且只接受Host和Origin头值匹配的握手请求。
在我看来,前进的道路是凌驾于这个方法之上:
ServerEndpointConfig.Configurator.checkOrigin(String originHeaderValue)
( Tomcat 8提供的实现总是返回true),但是我看到的问题是这个方法只有一个参数,而且我错过了主机头值来比较这个值。
另外,这个类不提供任何返回这些信息的方法,所以我认为这个方法是无用的,除非您正在将源标头值与以前已知的主机值或值集进行比较,但这也没有任何意义,因为我的应用程序可以在不同的、正在更改的主机名或I下看到。
我正在考虑在modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)的实现中执行这个验证,在这里我可以读取所有的头值,但是我非常肯定我误解了什么。
所以我的问题是:
执行此验证的正确方法是什么?
谢谢你,纳乔
发布于 2016-02-15 16:27:25
在深入研究这个问题之后,我得出结论,Websocket (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并没有考虑实现Host和Origin头验证的可能性。
作为一种解决办法,对于那些将websocket端点放在servlet堆栈后面的服务提供者(比如Tomcat,Websocket机器由servlet过滤器org.apache.tomcat.websocket.server.WsFilter触发),您可以创建一个外部过滤器,它允许线程本地访问请求,以便在checkOrigin()方法中使用它来获取Host头值。
这让我想知道为什么这种类型的检查不会比白名单解决方案更好,我只是发现了一个有趣的帖子:相同域请求的源和主机标头。
https://stackoverflow.com/questions/35398798
复制相似问题