固定SessionID 漏洞 攻击(session fixation attacks)

固定session 攻击:session fixation attacks
一个简单的登录控制
下面是一个最常用最简单的登录控制流程,通过表单提交用户名密码,servlet判断用户名密码,正确则写一个session,然后跳转到登录后的能够看到的页面
登录页面JSP

<body>
 <form action="SessionTestServlet" method="post"> 用户名:<input name="username" type="text" value=""/>
  密码:<input name="password" type="password" value=""/> <input name="submit" type="submit" value="Submit"/> 
 </form> 
 </body>

SessionTestServlet

protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { 
    HttpSession session = request.getSession(); 
    String username=request.getParameter("username"); 
    String password=request.getParameter("password"); 
    if("admin".equals(username) && "pass".equals(password)){             session.setAttribute("login", true);  response.sendRedirect("hello.jsp"); }
else{ 
    response.sendRedirect("login.jsp"); 
    } }

登录后的页面hello.jsp

<body> <% boolean isLogin = (Boolean)request.getSession().getAttribute("login"); if(isLogin!=null){ out.print("Welcome"); }else{ out.print("Sorry!"); } %> </body>

匿名SessionID
运行着个简单的demo后,打开login.jsp,使用firebug或chrome会发现,即使没有登录,我们也会有一个JSESSIONID,这是由服务器端在会话开始是通过set-cookie来设置的匿名SessionId
这里写图片描述

可以发现,登录前和登录后的JSESSIONID并没有改变,那么这就是一个固定SessionID的漏洞(详见《黑客攻防技术宝典-web实战》第七章)

简单的漏洞攻击
第一步,需要获取被攻击用户的JSESSIONID,可以通过给被攻击用户一个伪造的JSESSIONID,使其用该JESSIONID登录,获取用户登录后的JESSIONID。(这里作为示范,直接从浏览器中获取)
第二步,等被攻击用户登录,是JESSIONID成为已登录状态。
第三步,伪造请求,访问登录后的资源。
在用户登录使该JSESSIONID称为已登录的ID后,攻击者就可以利用这个ID伪造请求访问登录后的资源。下面是一个简单的python脚本

#!/bin/python import urllib, urllib2 request = urllib2.Request('http://localhost:9090/sec/hello.jsp') opener = urllib2.build_opener() //设置窃取的JSESSIONID request.add_header('Cookie','JSESSIONID=CF2D43B2C433F1A9FD78CE9D01E2E52D') hellodata=opener.open(request).read() print hellodata

执行该脚本,结果如下:
这里写图片描述
能够看到需要登录的页面

漏洞分析处理
出现该问题的主要原因是登录控制使用的固定的SessionID,登录前与登录后的SessionID是一样的。这样就使得攻击者可以简单的伪造一个SessionID诱使用户使用该SessionID登录,即可获取登录权限。如果配合XSS漏洞,则更加可以轻易获取登录权限。避免这一漏洞的方法主要有两种:
1.在登录后重置sessionID
在登录验证成功后,通过重置session,是之前的匿名sessionId失效,这样可以避免使用伪造的sessionId进行攻击。代码如下

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    String username=request.getParameter("username"); 
    String password=request.getParameter("password"); 
    if("admin".equals(username) && "pass".equals(password)){ 
    //使之前的匿名session失效 
    request.getSession().invalidate();  
    request.getSession().setAttribute("login", true);  response.sendRedirect("hello.jsp"); }
    else{ response.sendRedirect("login.jsp"); } }

这样登录前与登录后的sessionID就不会相同
这里写图片描述
2.设置httpOnly属性
httponly是微软对cookie做的扩展,该值指定 Cookie 是否可通过客户端脚本访问, 解决用户的cookie可能被盗用的问题,减少跨站脚本攻击
主流的大多数浏览器已经支持此属性。httpOnly是cookie的扩展属性,并不包含在servlet2.x的规范里,因此一些javaee应用服务器并不支持httpOnly,针对tomcat,>6.0.19或者>5.5.28的版本才支持httpOnly属性,具体方法是在conf/context.xml添加httpOnly属性设置

<Context useHttpOnly="true"> ... </Context>

另一种设置httpOnly的方式是使用Tomcat的servlet扩展直接写header

response.setHeader( "Set-Cookie", "name=value; HttpOnly");
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Session 是一种在 Web 应用程序中跟踪用户状态的机制。在用户登录时,可以创建一个 session,将用户的身份验证信息存储在 session 中,并将 session ID 存储在 cookie 中发送给客户端,以便于后续的访问。 以下是一个简单的实现方法: 1. 在用户登录成功时,创建一个 session,并将用户信息存储在其中。例如: ``` session_start(); $_SESSION['user_id'] = $user_id; ``` 2. 将 session ID 存储在 cookie 中发送给客户端。例如: ``` setcookie('session_id', session_id(), time() + 3600, '/'); ``` 其中,第一个参数为 cookie 的名称,第二个参数为 session ID,第三个参数为过期时间(这里设置为一个小时),第四个参数为 cookie 的路径。 3. 在后续的请求中,通过检查 cookie 中的 session ID 来验证用户的身份。例如: ``` session_start(); if (!isset($_SESSION['user_id']) || empty($_COOKIE['session_id']) || $_COOKIE['session_id'] != session_id()) { header('Location: login.php'); exit; } ``` 其中,第一行代码开始或恢复一个 session,第二行代码检查 session 中是否保存了用户信息,第三行代码检查 cookie 中是否包含 session ID,第四行代码检查 cookie 中的 session ID 是否与当前 session ID 相同。如果任何一个条件不满足,则重定向到登录页面。 注意:为了保护 session 的安全性,需要在服务器端禁用 session ID 的传递,以避免 session fixation 攻击。可以通过设置 session.use_only_cookies 为 true 来实现这一点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值