每页多个有状态iframe将覆盖JSESSIONID?

时间:2010-03-21 21:07:25

标签: tomcat cookies url-rewriting jsessionid

寻找某人确认或反驳我的理论 部署两个iframe指向两个不同的有状态页面 相同的域可能导致JSESSIONID被覆盖。这就是我 意味着:

设置

  1. 假设您有两个页面需要HttpSession状态(会话 亲和力)正常运作 - 部署在http://www.foo.com/ page1 http://www.foo.com/ 第2页
  2. 假设www.foo.com是运行Tomcat的单个主机(6.0.20,fwiw) 它使用JSESSIONID作为会话ID。
  3. 假设这些页面被转换为两个iframe小部件 嵌入第三方网站:http://www.site.com/page1“ /> (和/ page2)
  4. 假设有第三方网站希望放置两个小部件 同一页http://www bar.com /foowidgets.html
  5. 是否会出现以下竞争条件?

    1. 新访客访问http://www.bar.com/foowidgets.html
    2. 浏览器开始加载foowidgets.html中的URL,包括两者 iframe的'src'网址
    3. 因为浏览器打开多个并发连接 浏览器碰巧遇到了同一个主机(在chrome / ff情况下最多6个) 同时发出http://www.foo.com/page1和{}的请求 http://www.foo.com/page2
    4. tomcat @ foo.com几乎同时收到两个请求, 第一次调用getSession()(在两个不同的线程上)和 懒惰地创建了两个HttpSession,因此创建了两个JSESSIONID 值$ Page1和$ Page2。请求还将数据填充到各自的数据中 会话(将需要数据来处理后续请求)
    5. 假设浏览器首先收到对page1的响应 请求。浏览器为HOST www.foo.com
    6. 设置cookie JSESSIONID = $ Page1
    7. 接收到对page2请求的下一个响应和浏览器 用$ Page2
    8. 覆盖HOST www.foo.com的cookie JSESSIONID
    9. 用户点击foowidgets.html上“page1”iframe中的内容; 浏览器发出第二个请求 http://www.foo.com/page1?action=doSomethingStateful。那个要求 携带JSESSIONID = $ Page2(而不是$ Page1 - 因为cookie值是 重写)
    10. 当foo.com收到此请求时,会查找错误 HttpSession实例(因为JSESSIONID键是$ Page2而不是 $ 1页)。 Foobar的!
    11. 上述情况会发生吗?我是这么认为的,但我希望得到确认。

      如果上述内容显而易见,那么给出了哪些解决方案 我们想支持每页多个iframe吗?我们没有坚定的 需要iframe共享相同的HttpSession,尽管如此 对人好点。如果解决方案仍然会规定一个 每个iframe单独的HttpSession,它当然是强制性的 iframe 1最终没有引用iframe 2的httpSession状态 而不是自己。

      我能想到的是:

      1. 将page1和page2映射到不同的域(操作开销)
      2. 使用网址重写而不使用Cookie(搞乱分析)
      3. 其他什么?
      4. 非常感谢, -nikita

3 个答案:

答案 0 :(得分:1)

TL; DR 方案是正确的,一个会话覆盖另一个会话,两个页面共享会话;但没关系。


在上面的示例中,您有两个几乎同时发生的无状态匿名请求。

换句话说,请求绝对没有任何独特之处;将返回两个通用页面。这两个页面都有新的JSESSIONID,不是因为竞争,而是因为请求本身是匿名的,因此基本上要求Tomcat创建新的会话。

让我们假设page2赢得了JSESSIONID速度竞赛,浏览器现在有了page2 cookie。然后,用户单击第1页中的操作。我认为你的请求将标有page2 cookie是正确的。

但那是什么?

Page1中不能包含任何与会话相关的信息,因此没有特定于用户的信息。因此,它的操作可以没有与会话相关的状态(刚刚创建了状态)。如果没有特定的会话相关状态,那么它与'错误的'JSESSIONID一起出现就没有问题。

以另一种方式看待它:如果在第1页的请求之前已经完全处理了page2的请求,那么page1将以何种方式不同?我看不出任何差异。如果两个场景中返回的HTML没有差异,那么交换JSESSIONID无关紧要。

OTOH,如果用户已经访问过bar.com,那么对page1和page2的请求将与相同的JSESSIONID相关联,返回的页面是正确的,并且在foo.com的世界中一切都很好。

一个问题:如果您已启用CSRF保护。 CSRF库修改返回页面中的所有URL以包含额外参数。 CSRF保护库检查其安全令牌与JSESSIONID匹配的所有传入请求。如果page1使用cookie作为page2,则CSRF保护将拒绝伪造的请求。

如果每个iframe必须有一个会话:请使用网址重写。这最初设计用于在浏览器不接受cookie时管理会话。它工作得很好,但URL看起来很讨厌。

答案 1 :(得分:0)

你所说的是正确的,这是方法HttpServletResponse.encodeURL()的存在理由。

如果包含两个iframe的页面与page1和page2位于同一上下文中,则iframe中的网址应使用此方法进行编码,或使用JSTL的< c:url>获取。标签

如果尚未定义cookie,它将在URL中添加JSESSIONID。

答案 2 :(得分:0)

如果page1和page2使用不同的上下文,它们都将通过第三方iframe工作,而不会干扰彼此的范围。

有多种方法可以在JSP中控制会话。这个问题的首要答案可能会帮助您找到合适的解决方案: Under what conditions is a JSESSIONID created?