• Session攻击


    1、认证和授权

            很多时候,人们会把“认证”和“授权”两个概念搞混,实际上“认证”和“授权”是两件事情,认证的英文是Authentication,授权则是Authorization。分清楚这两个概念其实很简单,只需要记住:认证的目的是为了认出用户是谁,而授权的目的是为了决定用户能够做什么。

            形象地说,假设系统是一间屋子,持有钥匙的人可以开门进入屋子,那么屋子就是通过“锁和钥匙的匹配”来进行认证的,认证的过程就是开锁的过程。钥匙在认证过程中,被称为“凭证”(Credential),开门的过程,在互联网里对应的是登录(Login)。可是开门之后,什么事情能做,什么事情不能做,就是“授权”的管辖范围了。

            如果进来的是屋子的主人,那么他可以坐在沙发上看电视,也可以进到卧室睡觉,可以做任何他想做的事情,因为他具有屋子的“最高权限”。可如果进来的是客人,那么可能就仅仅被允许坐在沙发上看电视,而不允许其进入卧室了。

            “能否进入卧室”这个权限被授予的前提,是需要识别出来者到底是主人还是客人,所以如何授权是取决于认证的。现在问题来了,持有钥匙的人,真的就是主人吗?如果主人把钥匙弄丢了,或者有人造了把一模一样的钥匙,那也能把门打开,进入到屋子里。这些异常情况,就是因为认证出现了问题,系统的安全直接受到了威胁。钥匙仅仅是一个很脆弱的凭证,其他诸如指纹、虹膜、人脸、声音等生物特征也能够作为识别一个人的凭证。认证实际上就是一个验证凭证的过程。

            如果只有一个凭证被用于认证,则称为“单因素认证”;如果有两个或多个凭证被用于认证,则称为“双因素(Two Factors)认证”或“多因素认证”。一般来说,多因素认证的强度要高于单因素认证,但是在用户体验上,多因素认证或多或少都会带来一些不方便的地方。

    2、Session与认证

            密码与证书等认证手段,一般仅仅用于登录(Login)的过程。当登录完成后,用户访问网站的页面,不可能每次浏览器请求页面时都再使用密码认证一次。因此,当认证成功后,就需要替换一个对用户透明的凭证。这个凭证,就是SessionID。

            当用户登录完成后,在服务器端就会创建一个新的会话(Session),会话中会保存用户的状态和相关信息。服务器端维护所有在线用户的Session,此时的认证,只需要知道是哪个用户在浏览当前的页面即可。为了告诉服务器应该使用哪一个Session,浏览器需要把当前用户持有的SessionID告知服务器。最常见的做法就是把SessionID加密后保存在Cookie中,因为Cookie会随着HTTP请求头发送,且受到浏览器同源策略的保护。

            Cookie中保存的SessionlD,SessionID一旦在生命周期内被窃取,就等同于账户失窃。同时由于SessionID是用户登录之后才持有的认证凭证,因此黑客不需要再攻击登录过程(比如密码),在设计安全方案时需要意识到这一点。

    3、会话(Session)劫持

            会话劫持(Session hijacking)就是一种通过窃取用户SessionID后,使用该SessionID登录进目标账户的攻击方法,此时攻击者实际上是使用了目标账户的有效Session。如果SessionID是保存在Cookie中的,则这种攻击可以称为Cookie劫持。

    攻击步骤:

    1. 目标用户需要先登录站点;
    2. 登录成功后,该用户会得到站点提供的一个会话标识SessionID;
    3. 攻击者通过某种攻击手段捕获Session ID;
    4. 攻击者通过捕获到的Session ID访问站点即可获得目标用户合法会话。

    攻击者获取SessionID的方式有多种:

    1. 暴力破解:尝试各种Session ID,直到破解为止;
    2. 预测:如果Session ID使用非随机的方式产生,那么就有可能计算出来;
    3. 窃取:使用网络嗅探、本地木马窃取、XSS攻击等方法获得。 

    防御方法:

    1、Cookie HttpOnly。通过设置Cookie的HttpOnly为true,可以防止客户端脚本访问这个Cookie,从而有效的防止XSS攻击。

    response.setHeader("Set-Cookie","user="+request.getParameter("cookie")+";HttpOnly");

    SessionCookieConfig接口,用于操作会话Cookie,在ServletContextListener监听器初始化方法中进行设定即可

    1. @WebListener
    2. public class SessionCookieInitialization implements ServletContextListener {
    3. private static final Log log = LogFactory.getLog(SessionCookieInitialization.class);
    4. public void contextInitialized(ServletContextEvent sce) {
    5. ServletContext servletContext = sce.getServletContext();
    6. SessionCookieConfig sessionCookie = servletContext.getSessionCookieConfig();
    7. //设置HttpOnly
    8. sessionCookie.setHttpOnly(true);
    9. }
    10. public void contextDestroyed(ServletContextEvent sce) {
    11. }
    12. }

    2、Cookie Secure,是设置 COOKIE 时,可以设置的一个属性,设置了这个属性后,只有在 https 访问时,浏览器才会发送该 COOKIE。浏览器默认只要使用http 请求一个站点,就会发送明文 cookie,如果网络中有监控,可能被截获。如果 web 应用网站全站是 https 的,可以设置 cookie 加上 Secure 属性,这样浏览器就只会在 https 访问时,发送 cookie。攻击者即使窃听网络,也无法获取用户明文 cookie

    response.setHeader("Set-Cookie"," user="+request.getParameter("cookie")+";HttpOnly;Secure");

    或者

    1. @WebListener
    2. public class SessionCookieInitialization implements ServletContextListener {
    3. private static final Log log = LogFactory.getLog(SessionCookieInitialization.class);
    4. public void contextInitialized(ServletContextEvent sce) {
    5. ServletContext servletContext = sce.getServletContext();
    6. SessionCookieConfig sessionCookie = servletContext.getSessionCookieConfig();
    7. // 设置HttpOnly
    8. sessionCookie.setHttpOnly(true);
    9. sessionCookie.setSecure(true);
    10. }
    11. public void contextDestroyed(ServletContextEvent sce) {
    12. }
    13. }

    4、会话固定(Session fixation)

            会话固定(Session fixation)是一种诱骗受害者使用攻击者指定的会话标识(SessionID)的攻击手段。这是攻击者获取合法会话标识的最简单的方法。让合法用户使用黑客预先设置的sessionID进行登录,从而是Web不再进行生成新的sessionID,从而导致黑客设置的sessionId变成了合法桥梁。

            会话固定也可以看成是会话劫持的一种类型,原因是会话固定的攻击的主要目的同样是获得目标用户的合法会话,不过会话固定还可以是强迫受害者使用攻击者设定的一个有效会话,以此来获得用户的敏感信息。

            什么是Session Fixation呢?举一个形象的例子,假设A有一辆汽车,A把汽车卖给了B,但是A并没有把所有的车钥匙交给B,还自己藏下了一把。这时候如果B没有给车换锁的话,A仍然是可以用藏下的钥匙使用汽车的。这个没有换“锁”而导致的安全问题,就是Session Fixation问题。

    攻击步骤:

    1. 攻击者通过某种手段重置目标用户的SessionID,然后监听用户会话状态;
    2. 目标用户携带攻击者设定的Session ID登录站点;
    3. 攻击者通过Session ID获得合法会话

    攻击者如何才能让目标用户使用这个SessionID呢?如果SessionID保存在Cookie中,比较难做到这一点。但若是SessionID保存在URL中,则攻击者只需要诱使目标用户打开这个URL即可。 

    防御方法:【多个方法结合使用】

    1、每当用户登陆的时候就进行重置sessionID

    1. // 会话失效
    2. session.invalidate();
    3. // 会话重建
    4. session=request.getSession(true);

    2、sessionID闲置过久时,进行重置sessionID

    3、 禁用客户端访问Cookie,设置HttpOnly

    5、Session保持攻击

            一般来说,Session是有生命周期的,当用户长时间未活动后,或者用户点击退出后,服务器将销毁Session。Session如果一直未能失效,会导致什么问题呢?前面的章节提到session劫持攻击,是攻击者窃取了用户的SessionID,从而能够登录进用户的账户。

            但如果攻击者能一直持有一个有效的Session(比如间隔性地刷新页面’以告诉服务器这个用户仍然在活动),而服务器对于活动的Session也一直不销毁的话,攻击者就能通过此有效Session—直使用用户的账户,成为一个永久的‘后门。

    但是Cookie有失效时间,Session也可能会过期,攻击者能永久地持有这个Session吗?

            一般的应用都会给session设置一个失效时间,当到达失效时间后,Session将被销毁。但有一些系统,出于用户体验的考虑,只要这个用户还“活着”,就不会让这个用户的Session失效。从而攻击者可以通过不停地发起访问请求,让Session一直“活”下去。

    保持session长时间存活:

    1. <iframe id="iframe1" src=""/>

    Cookie永不过期:

    1. anehta.dom.persistCookie = function (cookieName){
    2. if(anehta.dom.checkCookie(cookieName)==false){
    3. return false;
    4. }
    5. try{
    6. document.cookie = cookieName + "=" + anehta.dom.getCookie(cookieName)+";" + "expires=Thu, 01-Jan-2038 00:00:01 GMT;";
    7. } catch( e){
    8. return false;
    9. }
    10. return true;
    11. }

    攻击者甚至可以为Session Cookie增加一个Expire时间,使得原本浏览器关闭就会失效的Cookie持久化地保存在本地,变成一个第三方Cookie(third-partycookie)。

    防护方案:
            常见的做法是在一定时间后,强制销毁Session。这个时间可以是从用户登录的时间算起,设定一个阈值,比如3天后就强制Session过期。

            但强制销毁Session可能会影响到一些正常的用户,还可以选择的方法是当用户客户端发生变化时,要求用户重新登录。比如用户的IP、UserAgent等信息发生了变化,就可以强制销毁当前的Session,并要求用户重新登录。

            最后,还需要考虑的是同一用户可以同时拥有几个有效Session。若每个用户只允许拥有一个Session,则攻击者想要一直保持一个Session也是不太可能的。当用户再次登录时,攻击者所保持的Session将被“踢出”。

  • 相关阅读:
    vue 修改v-for 循环内的item数据视图不刷新
    批量删除Docker容器
    (附源码)app智能手机的微课程学习系统 毕业设计 100909
    AI-windows下使用llama.cpp部署本地Chinese-LLaMA-Alpaca-2模型
    学习笔记-WinRM
    Java开发学习(四十三)----MyBatisPlus查询语句之查询投影
    后悔怎么没早点看到!腾讯T3整理实战书籍:(Spring MVC +MyBatis快速开发与项目实战pdf)
    手撸mybatis03: xml配置的解析与注册
    LeetCode 0503. 下一个更大元素 II
    SwiftUI SQLite数据库存储使用教程大合集(2022年版)
  • 原文地址:https://blog.csdn.net/weixin_52851967/article/details/126007598