[说明: 本文为 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问题等等
分享到:
相关推荐
"浏览器多窗口共用session引发的混乱"这个标题揭示了一个常见但往往被忽视的问题,即当用户在同一浏览器的不同窗口或标签页中打开同一个网站时,它们可能会共享同一份Session数据,这可能导致意料之外的行为和用户...
1. **非线程安全**:由于`Session`不是线程安全的,因此在多线程环境中,每个线程都应有自己的`Session`实例,以避免数据存取的混乱。 2. **轻量级**:`Session`的创建和销毁相对快速,降低了资源的消耗。 3. **第一...
当 Session 一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义,“面向连接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到对方接了电话通信才能开始。...
6. **Spring-Session与Redis集成**:将Session数据存储在Redis这样的分布式缓存中,实现高效、一致的Session共享。这是目前很多项目采用的方案。 **目前项目存在的问题** 项目中启动了两个服务,端口号分别为8080...
这是因为session通常依赖于服务器存储,当涉及到多服务器的集群环境时,不同服务器之间无法共享session数据,可能导致用户状态混乱。通过将session数据转换为cookie,客户端负责携带这些信息,避免了服务器间的同步...
与Cookie相比,Session更安全,因为它不直接将数据存储在客户端,而是由服务器管理,减少了数据篡改的风险。 一个Session通常涵盖一系列HTTP请求和响应,比如用户从登录到登出的整个过程。每个Session都有一个...
在ASP.NET开发中,SessionState是一项常用的技术,用于保存与客户端相关的状态信息。然而,仅依赖SessionState进行状态管理存在一定的局限性: 1. **弱类型的编程方式**:SessionState中存储的对象类型为`System....
默认情况下,PHP的session数据是存储在服务器的临时文件中,但这样的存储方式有安全隐患,比如服务器崩溃导致session信息丢失,以及服务器被多用户共用时可能出现的session数据混乱问题。将session数据存入数据库...
根据提供的文件信息,内容显得非常零散且缺乏上下文,看起来像是一系列与网络安全相关的术语、缩写和年份的混合。尽管信息不完整,但我们可以尝试从中提取和整理一些相关的知识点。 1. PPP (Point-to-Point ...
然而,Session本身并不具备线程安全特性,也就是说,如果多个线程共用同一个Session实例,可能会引发数据混乱,因为Session包含了与数据库交互的状态信息。 ThreadLocal模式是解决这个问题的有效方案之一。...
如果不注意线程安全,同样会导致数据混乱和业务逻辑错误。 **Struts action线程安全问题示例:** 假设我们有一个简单的Struts action,用于处理用户登录请求: ```java public class LoginAction extends Action ...
如果在输出内容后再尝试发送头信息,可能会导致浏览器解析混乱,或者由于内容与头信息顺序错误而无法正确处理请求。 例如,如果在`header("Location: some_page.php");`之后有任何输出,浏览器可能无法进行重定向,...
- **更新Session信息**:若有必要,可以更新Session中的信息,例如记录最后登录的IP地址或设备信息,以便于追踪和安全审计。 5. **强制下线**:通知客户端清除Cookie中的Session ID,确保用户不能继续访问系统。...
3. **重定向后的消息**:Flash Session常与重定向操作结合使用,例如: ```php return redirect('dashboard')->with('success', '操作成功'); ``` 4. **清除Flash Session**:虽然Flash Session会在第二个请求...
- **线程安全的内置对象**:`OUT`, `REQUEST`, `RESPONSE`, `SESSION`, `CONFIG`, `PAGE`, `PAGECONTEXT` 这些JSP内置对象是由容器管理的,它们在每次请求时都会被初始化,因此是线程安全的。 - **非线程安全的...
为了进一步增强安全性,可以结合这两种方法,即使用Session来快速响应请求,同时在数据库中记录用户状态,以便在服务器重启或其他Session丢失的情况下,仍能判断账号的登录状态。 **实现步骤:** 1. 用户尝试登录...
例如,Hibernate框架中,使用ThreadLocal来存储每个线程的Session实例,这样每个线程都有自己的Session,避免了线程间的数据混乱。以下是一个简单的例子: ```java public static final ThreadLocal<Session> ...
ThreadLocal是一种在Java中实现线程局部变量的方法,它可以保证每个线程都有自己的Session副本,确保线程安全。 #### 2.2 Session的创建与关闭 在Hibernate中,Session是与数据库交互的主要接口。创建Session通常...
使用Session-Manager可以帮助用户克服标签页过多导致的混乱,提高工作效率,尤其是在需要同时处理多个项目或研究主题时。它也可以作为临时保存待阅读文章或网页的工具,避免因为误操作丢失重要信息。 总之,...