`
smithfox
  • 浏览: 55224 次
  • 性别: Icon_minigender_1
  • 来自: hf
社区版块
存档分类
最新评论

session的混乱与安全

阅读更多

[说明: 本文为 http://www.smithfox.com/?e=32 原创, 转载请注明原文, 谢谢]

session的安全有两层意思:

1> 对最终客户来说, 不会因为session的share和造成混乱, 使end-user的信息泄漏以及其他安全问题

2> 对系统本身来说, 不会因为有hacker通过模拟sessionid和cookie来获取server信任进而进行恶意破坏

让我们逐层解释和展开问题:

1> 首先说明, 本文所有session专指Servlet HttpSession

2> 后台Session和Browser之间通过JSESSIONID来关联, JSESSIONID是Servlet标准,也是关键字, Servle规定Browser用Mem Cookie来存储JSESSIONID, 注意并不是disk cookie.一旦浏览器关闭后JSESSIONID就从PC消失, 更加安全.

3> Session也是一种很好的安全认证机制, 后台会标识session是不是已经被认证了, 如果是,就不会让用户再输入password. JSESSIONID可以被理解成为一个已经认证的key, 所以Session有安全问题.

4> Servlet容器不会构造相同的JSESSIONID, 客户端也很难预期JSESSIONID

5> HTTPS SSL等技术可以防止网络传输中有人恶意篡改JSESSIONID

6> 禁用Cookie的情况JSESSIONID就必须用URLRewrite. 我们可以通过对URL本身采用摘要算法,自认证来防止恶意篡改JSESSIONID.

比如:  http://www.smithfox.com/abc?x=x&y=y&JSESSIONID=sdfdfsdfsdfsdfsdf&HWD=4FE23AD9892C

HWD的值是对整个URL的一个摘要算法, 如果有人改动了URL,这个HWD值就对不上了, 前提应该是这个算法别人不知道的.

7> 用户在自己的PC上肯定是可以看到当前的JSESSIONID的, 就象就你在自己的日记中看到了自己备忘的password一样, 这个不是技术安全问题.

8> 一台机器有多个自然人在使用, 出现的JSESSIONID欺骗, 应该没有技术办法可以解决. 只能是end-user自己小心,用完就关闭Browser. 我想这应该是在情理之中的事, 你是合租被盗应该是怪不得小区保安的, 也是需要自己平时提高防盗意识,呵呵.

9> 最近看到Tomcat7有个新的特性说是支持"防JSESSIONID劫持", 这个需要更多了解.

10> User和Session的关系.

Session是只认JSESSIONID不认人的, 包括自然人和系统Account. 这个问题比较搞.

我们用EndUser来表示自然人, User-Account表示系统帐号, 我们分析以下几种情况

10.1> 两个EndUser共用一个UserAccount并且在同一台PC, 这个混乱不是技术问题, 大家都可以理解

10.2> 两个EndUser分别使用不同的UserAccount在同一台PC, 这个是合租情况, 造成混乱不一定是技术问题

10.3> 某EndUser有两个UserAccount在同一台PC上, 我们需要考虑JSESSIONID在client端可以会混乱的问题.

因为不同的浏览器对于Cookie share的策略不同, 我们按程序设计必须按最容易出问题的Case想,比如IE8.

无论你是IE多窗口还是多TAB都是Share Cookie的. 所以总的指导方针是在client端做一些机制不允许用户这么做.

Google的gmail就是这么做的, 你可以一台机器上用IE打开两个不同的gmail account(两个窗口或是两个TAB都行),点新email或是其他需要和后台交互的行为时,gmail会退出一个,提示让你重新login并且gmail account已经固定为后输入的User-Account.

具体在Client怎么防止两个Account还需高手指点.

10.4> 某EndUserA用自己的UserAccountA先已经login,再访问另一个UserAccountB的资源,而且该资源是需要访问密码的. 

这种情况,往往因为后台Session设计的层次不清晰,造成了UserAccountA无需Password就直接访问到了UserAccountB的资源. 而且这个解决方案不能放在Client端, 因为访问UserAccountB的资源可能就是一个在Email中的Link,这个click动作客户端程序JavaScript是无法拦截的.

10.5> 总结来说:  

11> 从第10>点可以看出, session和自然人或是UserAccount有着千丝万缕的联系,但不是所有的系统只有User这一层业务概念,所以我们需要理解后台的Session分划和设计好Session.Attribute层次.

我们以一个假设业务模型为例说明问题: 这是一个只面向企业的图片共享web服务, 可以为多个公司(企业)提供服务, 用户必须属于某一个公司, 用户可以创建"图片分组", 图片分组可以设置为private(需要密码访问), 也可以直接公开. 图片分组是公司财产, user可以创建"图片分组", 但是图片分组资源是归属公司, 同一公司内部的所有user可以直接访问图片分组(如果是公开), 也可以通过password(如果需要)访问图片分组.

这个业务模型中, 既有比User更高层的概念, 比如公司. 也有比User更底的概念, 比如用户的上传图片分组(imageGroup).

11.1> 不同的war包部署在tomcat,不同的war包之间的session是不会混乱的, 这个是由tomcat架构决定的. 另他的没有做过调查, 也有可能是Servlet标准, 有高手可以帮确认一下.

11.2> 多个公司又是运行在同一个tomcat application内, 怎么防止不同公司之间的session混乱

可以采用类似于防止重复提交的技术, 首先做一个优先级很高的filter, 每次reqeust和response都需要经过这个filter

在所有login模块, 设置一个ticket cookie,写入当前company信息, 每个reqeust到达的第一步就是检测client cookie和当前的URL信息, 以及session信息是否一致, 如果enduser是从一个company中click了一个其他company的link, 该filter就会发现ticket信息不一致, 然后就强制logout, 再次让user login. 并且每次response时做ticket的改动, 使client无法模拟

11.3> 怎么防止imageGroup信息混乱

Session本身是一个集合, 具体还是使用session.attribute["key"]

Session本身是User level的, 对于低于User level的信息, 需要好好规划attribute key

想像这样的case:

有两个imageGroup, 一个是public的, 一个是需要password的, 

http://www.smithfox.com/companyIBM/public_images/

http://www.smithfox.com/companyIBM/password_images/

后台对imageGroup输入密码逻辑的伪代码如下:

boolean needpasswd = true;
if(session.getAttribute("NEED_PASSWORD") == null){
session.setAttribute("NEED_PASSWORD", needpasswd);
boolean needpasswd = 一个很耗时很复杂的验证函数(user, imageGroup, xxx);
} else{
needpasswd session.getAttribute("NEED_PASSWORD");
}
if (needpasswd ){
showPasswordDialog() ;

看出什么问题没?

应该将上面的代码中的所有attribute key改成 "NEED_PASSWORD"+{imageGroupID}

否则用户只要先看了一个public后, 后面的所有图片分组都无需passwd就可以访问了, 即使这个imageGroup是private的.

13> 在用session之前一定需要检查是否真的一定需要session来解决, 比如只是想传value到JSP page, request.setAttribte()更适合

14> 比较小而多的业务对象,如果必须save在session一定要及时removeAttribute否则session用的内存会暴涨.

因为Session不会因为客户端不用了,就会自动清理,而是必须到SessionTimeOut才会,如果在SessionTimeOut期间内有很多的对象在Session内,就会有问题。所以需要即时清理已经不用的Session.Attribute

15> Cookie和Session一样, 同样需要注意 cookie key的层次问题,以及过期问题,domain, path问题等等

 

分享到:
评论
10 楼 76529775 2011-10-14  
围观
困扰
9 楼 smithfox 2010-11-26  
grandboy 写道
haitaohehe 写道
没有高手给出解决方案啊? 另外楼主如果把这篇帖子的内容格式整理一下,并且画几张图前来围观的人会更多的,呵呵。。

猜测一下,我看gmail都在页面上保留一个user account, 每次访问是不是可以用这个页面上的account和服务器端session进行比较,如果不一致的话,就认为是这个account登录已经过期, 要求重新登录.这时只有第二个account是有效的.

不确定是不是这样的原理. 我现在想不允许同时使用一个account在多台机器登录简单一点的方法,不知道怎么做更简单有效.


"不允许同时使用一个account在多台机器登录": 我没有写在这篇文章上面, 因为我认为这个不是session的问题,而是User方面的问题. 管理他们之间有联系

我在文章中的gmail问题是:
"不允许在同一台机器上同时用多个account",

其实这个问题主要还是client share cookie的问题.
不在一台机器上, 或是一台机器上的两种不同浏览器, 都没有问题, 因为不share cookie, 就不会share jsessionid, 也就不会混乱
8 楼 grandboy 2010-11-26  
haitaohehe 写道
没有高手给出解决方案啊? 另外楼主如果把这篇帖子的内容格式整理一下,并且画几张图前来围观的人会更多的,呵呵。。

猜测一下,我看gmail都在页面上保留一个user account, 每次访问是不是可以用这个页面上的account和服务器端session进行比较,如果不一致的话,就认为是这个account登录已经过期, 要求重新登录.这时只有第二个account是有效的.

不确定是不是这样的原理. 我现在想不允许同时使用一个account在多台机器登录简单一点的方法,不知道怎么做更简单有效.
7 楼 haitaohehe 2010-11-26  
没有高手给出解决方案啊? 另外楼主如果把这篇帖子的内容格式整理一下,并且画几张图前来围观的人会更多的,呵呵。。
6 楼 pikenlike_123 2010-11-24  
写的很好,我往往在写程序时忽略session的重要性,看到该贴子收益很多
5 楼 smithfox 2010-11-22  
lz_cleaner 写道
原创地址是tomcat的主页了,在调整中么?

http://www.smithfox.com 的托管方有一些问题, 大家可以在javaeye里讨论. 呵呵
4 楼 lz_cleaner 2010-11-22  
原创地址是tomcat的主页了,在调整中么?
3 楼 jcs7575 2010-11-22  
haitaohehe 写道
写的很好,对于 10.3 的情况在你博客中我举了个163邮箱的例子,和你举的gmail例子是一样的,期待高手的解决方案,呵呵。。。


普通的web应用倒是可以使用cookie记录的形式,直接定位为后输入的user,提示重新login的就不知道了。同样期待高手
2 楼 haitaohehe 2010-11-21  
写的很好,对于 10.3 的情况在你博客中我举了个163邮箱的例子,和你举的gmail例子是一样的,期待高手的解决方案,呵呵。。。
1 楼 smithfox 2010-11-20  
在 junxy(xieyujun2006) 同学的提醒下,重新整理了这篇Blog,完善了User和Session关系一节.

欢迎大家指正我的错误.

相关推荐

    浏览器多窗口共用session引发的混乱

    "浏览器多窗口共用session引发的混乱"这个标题揭示了一个常见但往往被忽视的问题,即当用户在同一浏览器的不同窗口或标签页中打开同一个网站时,它们可能会共享同一份Session数据,这可能导致意料之外的行为和用户...

    Hibernate_Session_Transaction

    1. **非线程安全**:由于`Session`不是线程安全的,因此在多线程环境中,每个线程都应有自己的`Session`实例,以避免数据存取的混乱。 2. **轻量级**:`Session`的创建和销毁相对快速,降低了资源的消耗。 3. **第一...

    php5的session详解.doc

    当 Session 一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义,“面向连接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到对方接了电话通信才能开始。...

    分布式Session解决方案.docx

    6. **Spring-Session与Redis集成**:将Session数据存储在Redis这样的分布式缓存中,实现高效、一致的Session共享。这是目前很多项目采用的方案。 **目前项目存在的问题** 项目中启动了两个服务,端口号分别为8080...

    nginx session共享的问题.docx

    这是因为session通常依赖于服务器存储,当涉及到多服务器的集群环境时,不同服务器之间无法共享session数据,可能导致用户状态混乱。通过将session数据转换为cookie,客户端负责携带这些信息,避免了服务器间的同步...

    多php服务器实现多session并发运行

    与Cookie相比,Session更安全,因为它不直接将数据存储在客户端,而是由服务器管理,减少了数据篡改的风险。 一个Session通常涵盖一系列HTTP请求和响应,比如用户从登录到登出的整个过程。每个Session都有一个...

    ASP.NET应用下基于SessionState的状态编程框架解决方案.docx

    在ASP.NET开发中,SessionState是一项常用的技术,用于保存与客户端相关的状态信息。然而,仅依赖SessionState进行状态管理存在一定的局限性: 1. **弱类型的编程方式**:SessionState中存储的对象类型为`System....

    ThinkPHP实现将SESSION存入MYSQL的方法

    默认情况下,PHP的session数据是存储在服务器的临时文件中,但这样的存储方式有安全隐患,比如服务器崩溃导致session信息丢失,以及服务器被多用户共用时可能出现的session数据混乱问题。将session数据存入数据库...

    网络与信息安全.pdf

    根据提供的文件信息,内容显得非常零散且缺乏上下文,看起来像是一系列与网络安全相关的术语、缩写和年份的混合。尽管信息不完整,但我们可以尝试从中提取和整理一些相关的知识点。 1. PPP (Point-to-Point ...

    Hibernate用ThreadLocal模式(线程局部变量模式)管理Session

    然而,Session本身并不具备线程安全特性,也就是说,如果多个线程共用同一个Session实例,可能会引发数据混乱,因为Session包含了与数据库交互的状态信息。 ThreadLocal模式是解决这个问题的有效方案之一。...

    servlet与Struts action线程安全问题分析

    如果不注意线程安全,同样会导致数据混乱和业务逻辑错误。 **Struts action线程安全问题示例:** 假设我们有一个简单的Struts action,用于处理用户登录请求: ```java public class LoginAction extends Action ...

    PHP中header和session_start前不能有输出原因分析

    如果在输出内容后再尝试发送头信息,可能会导致浏览器解析混乱,或者由于内容与头信息顺序错误而无法正确处理请求。 例如,如果在`header("Location: some_page.php");`之后有任何输出,浏览器可能无法进行重定向,...

    J2EE限制同一账号同一时刻只能一个用户登录使用,向QQ一样

    - **更新Session信息**:若有必要,可以更新Session中的信息,例如记录最后登录的IP地址或设备信息,以便于追踪和安全审计。 5. **强制下线**:通知客户端清除Cookie中的Session ID,确保用户不能继续访问系统。...

    Laravel开发-flash

    3. **重定向后的消息**:Flash Session常与重定向操作结合使用,例如: ```php return redirect('dashboard')->with('success', '操作成功'); ``` 4. **清除Flash Session**:虽然Flash Session会在第二个请求...

    编写线程安全的JSP程序

    - **线程安全的内置对象**:`OUT`, `REQUEST`, `RESPONSE`, `SESSION`, `CONFIG`, `PAGE`, `PAGECONTEXT` 这些JSP内置对象是由容器管理的,它们在每次请求时都会被初始化,因此是线程安全的。 - **非线程安全的...

    同一账号不能同时登陆

    为了进一步增强安全性,可以结合这两种方法,即使用Session来快速响应请求,同时在数据库中记录用户状态,以便在服务器重启或其他Session丢失的情况下,仍能判断账号的登录状态。 **实现步骤:** 1. 用户尝试登录...

    java面试题汇总

    例如,Hibernate框架中,使用ThreadLocal来存储每个线程的Session实例,这样每个线程都有自己的Session,避免了线程间的数据混乱。以下是一个简单的例子: ```java public static final ThreadLocal<Session> ...

    2.Hibernate-02-一级缓存详细教案1

    ThreadLocal是一种在Java中实现线程局部变量的方法,它可以保证每个线程都有自己的Session副本,确保线程安全。 #### 2.2 Session的创建与关闭 在Hibernate中,Session是与数据库交互的主要接口。创建Session通常...

    session-manager:简单但功能强大的Chrome标签集管理

    使用Session-Manager可以帮助用户克服标签页过多导致的混乱,提高工作效率,尤其是在需要同时处理多个项目或研究主题时。它也可以作为临时保存待阅读文章或网页的工具,避免因为误操作丢失重要信息。 总之,...

Global site tag (gtag.js) - Google Analytics