Security GWT会话和XSRF-最佳解决方案?

Security GWT会话和XSRF-最佳解决方案?,security,session,gwt,csrf,Security,Session,Gwt,Csrf,好的,首先我在阅读的时候有点困惑 请记住-您决不能依赖中发送到服务器的sessionID cookie头;只查看GWT应用程序发送的sessionID 在发送到服务器的消息的有效负载中明确显示 当时,因为我没有完全理解XSRF的本质,我想:为什么id如何传输很重要 然后我阅读了,现在我了解到XSRF在不知道cookie内容的情况下仍能工作(您的浏览器只是将其附加到请求中,因此您可以利用浏览器对cookie内容的了解-尽管浏览器不会告诉“您”或攻击者有关该内容的信息。cookie内容本身不会受到该

好的,首先我在阅读的时候有点困惑

请记住-您决不能依赖中发送到服务器的sessionID cookie头;只查看GWT应用程序发送的sessionID 在发送到服务器的消息的有效负载中明确显示

当时,因为我没有完全理解XSRF的本质,我想:为什么id如何传输很重要

然后我阅读了,现在我了解到XSRF在不知道cookie内容的情况下仍能工作(您的浏览器只是将其附加到请求中,因此您可以利用浏览器对cookie内容的了解-尽管浏览器不会告诉“您”或攻击者有关该内容的信息。cookie内容本身不会受到该攻击的影响)。因此,任何知道cookie内容的证据都会验证请求不是XSRF的一部分

我不喜欢GWT()实现的解决方案,因为它需要单独调用服务器。请告诉我我的ansatz是否安全,我是否正确理解XSRF内容:

为了防止XSRF,我只需在执行RPC调用时将cookie中包含的会话ID复制到一些非标准HTTP头字段中,即“X-MY-GWT-session-ID:$sessionId”。

这样,我就不需要在应用程序启动期间进行任何额外的调用,因为如果会话不再有效,则在gwt应用程序交付期间通过销毁cookie已经完成了会话验证(请参阅)

下面是完整的安全实现:

  • 注册:客户端通过RPC调用向服务器提交明文凭据,服务器在注册期间使用哈希将密码存储在服务器数据库()中
  • 登录:客户端通过https+RPC发送明文pwd,检查服务器上的密码,如果确定:存储并返回(通过https)随机UUID。UUID是存储在服务器和客户端上的共享秘密,用于在可能的多个浏览器会话中识别经过身份验证的用户,以避免用户每次访问站点时都需要登录
  • 如果会话不再有效,服务器将cookie过期时间设置为0,以便客户端清除会话id,GWT应用程序检测到它需要重新验证
  • 在服务器端,仅接受通过特殊HTTP头字段发送的会话UUID,以防止XSRF
  • 在客户端处理无效会话(没有会话cookie或RPC请求生成的身份验证失败)
  • 为了防止在gwt应用程序加载后不久重新进行身份验证,服务器端的devlivery机制(即index.jsp)会在超时实际发生之前的某个时间删除cookie—在几秒钟后交付页面并请求身份验证有点愚蠢
GWT部件的示例源可在此处找到:。该解决方案基本上使用GWT XSRF类,但将MD5哈希会话ID直接嵌入到网页中,而不是通过单独的RPC调用获取令牌。客户机实际上从不调用任何与cookie相关的代码,服务器只在jsp页面中嵌入了一个
request.getSession().getId()
调用

有什么意见、建议、批评吗?我错过了重要的东西吗?

免责声明:我不是安全专家


实际上,如果您通过RPC调用获得xsrf令牌,那么您将受到xsrf的影响,因为攻击者可能伪造这两个请求(但这是非常不可能的,因为它必须读取第一个调用的响应,这在大多数情况下是由请求的跨源性质和/或执行方式所禁止的)

因此,理想情况下,您可以通过任何方式向GWT应用程序提供您的xsrf令牌。
您通常希望会话cookie无法通过脚本访问(
HttpOnly
flag),因此您需要找到另一种传递值的方法(例如,将其作为JS变量或特殊HTML元素上的特殊HTML属性写入交付给浏览器的HTML主机页中,并使用GWT通过
字典
、JSNI或DOM读取)


此外,您可能希望同时使用cookie和请求头来验证请求(它们必须匹配),或者您可能容易受到会话固定攻击(可能还需要XSS漏洞才能使其真正有用)

“如果您通过RPC调用获得xsrf令牌,则您将受到xsrf的影响”-为什么?您只有在交换正确的凭据(登录)时才能获得它。“令牌”(会话id)存储在客户端的cookie中。如何在不首先识别客户端的情况下将其放入主机页?关于会话固定的内容,我必须首先阅读该内容。我说的是
XsrfTokenServiceServlet
,它只读取auth cookie。是的,听起来有问题,尽管我没有看过thor应该是因为一个额外的请求和对整个servlet堆栈的重写看起来有点奇怪。另一方面,我们应该能够相信响应只会在相应的请求发出的地方发送,不是吗?我将使用AOP检查对单个调用的访问,并将身份验证信息放在有效负载之外似乎总是更好的走吧。