zoukankan      html  css  js  c++  java
  • Cookies欺骗分析与防护

    今天来谈谈cookies欺骗是怎么回事以及如何避免。

    用户在登录之后通常会保存用户信息,以便在其他需要权限的页面去验证用户信息是否具有访问权限。

    有同学说我在登录的时候已经很注意SQL注入问题了,还有什么不安全的地方么?

    当然有!这个要首先谈一个问题,那就是用户身份验证的流程 如下图:

    因此我们可以看出,一个页面是否能够被访问,判断依据是通过存储信息区域中用户的信息来判断的

    而登录页面的作用就是 验证 用户输入的用户名+密码的组合是否在数据库中存在,如果存在则把信息保存在存储信息的区域,以便各个页面去判断权限

    OK,理清这个思路之后我们的重点就来了,那个信息存储区域对于我们来说至关重要,一般常见的有两种形式,session和cookies

    session和cookies同样都是针对单独用户的变量(或者说是对象好像更合适点),不同的用户在访问网站的时候 都会拥有各自的session或者cookies,不同用户之间互不干扰。

    他们的不同点是:

    1,存储位置不同

    session在服务器端产生,比较安全,但是如果session较多则会影响性能

    cookies在客户端产生,安全性稍弱

    2,生命周期不同

    session生命周期 在指定的时间(如20分钟)到了之后会结束,不到指定的时间,也会随着浏览器进程的结束而结束。

    cookies默认情况下也随着浏览器进程结束而结束,但如果手动指定时间,则不受浏览器进程结束的影响。 

    由于如果用户信息使用session保存的话,用户信息往往会丢失而需要重新登录,使用cookies的话则可以长时间有效比较利于用户体验,那session的情况我们不讨论,下面说说使用cookies保存用户信息的情况。

    我们首先创建两个页面分别是Login.aspx和Main.aspx。Login.aspx用于获取并保存用户信息到cookies中,Main.aspx则用户验证用户是否有权访问本页面,我们在本例中设定,登录用户有权访问,匿名(未登录)用户,拒绝访问。

    首先来看Login.aspx 我们先创建两个按钮

    “获取登录状态”按钮会 把信息保存到cookies中,这里仅保存UID,然后重定向到Main.aspx

    “未获取登录状态”按钮 直接重定向到Main.aspx 进行匿名访问

    Login.aspx.cs 程序代码:

     1     protected void Page_Load(object sender, EventArgs e)
     2     {
     3         //每次加载登录页面 清理UID 清除登录状态
     4         Response.Cookies["uid"].Value = "0";
     5     }
     6     protected void Button1_Click(object sender, EventArgs e)
     7     {
     8         //验证步骤略过,假设用户通过验证并且得到如下信息:
     9 
    10         int uid = 1; //用户唯一ID
    11         string username = "admin"; //用户名
    12         string userpwd = "123456"; //用户密码
    13 
    14         //接下来要保存用户登录状态
    15         Response.Cookies["uid"].Value = uid.ToString();
    16 
    17         //跳转到登录后的页面
    18         Response.Redirect("Main.aspx");
    19 
    20     }
    21     protected void Button2_Click(object sender, EventArgs e)
    22     {
    23         //未经验证直接进入Main.aspx
    24         Response.Redirect("Main.aspx");
    25     }

    在Main.aspx中进行验证用户是否已经登录

     1     protected void Page_Load(object sender, EventArgs e)
     2     {
     3         CheckLogin();
     4     }
     5 
     6 
     7     private void CheckLogin()
     8     {
     9         if (Request.Cookies["uid"] != null && GetUserInfo(int.Parse(Request.Cookies["uid"].Value), "") != "")
    10         {
    11             Response.Write(GetUserInfo(int.Parse(Request.Cookies["uid"].Value), "username") + "已登录");
    12         }
    13         else
    14         {
    15             Response.Write("您尚未登陆,<a href='login.aspx'>点此登录</a>");
    16         }
    17     }
    18 
    19 
    20     /// <summary>
    21     /// 模拟一个获取用户信息的方法
    22     /// 然而实际操作中需要通过ID查询数据库来获取用户信息
    23     /// 这里为了方便演示就直接return固定的值了
    24     /// </summary>
    25     /// <param name="uid"></param>
    26     /// <param name="key"></param>
    27     /// <returns></returns>
    28     private string GetUserInfo(int uid, string key)
    29     {
    30         if (uid == 1) //这里只设置uid为1的用户,其他的UID的用户不存在
    31         {
    32             switch (key)
    33             {
    34                 case "username": return "admin";
    35                 case "password": return "123456";
    36                 default: return "null";
    37             }
    38         }
    39         else
    40         {
    41             return "";
    42         }
    43     }

     OK,我们来测试一下,点击获取登录状态,实际上相当于用admin,123456这个组合来登录。

    好的,登录成功,我们再来测试下匿名登录,点击未获取登录状态

    事情好像比我们想象的要顺利,目前来说我们想要的效果已经都实现了,但是事实上真的是这样吗,显然不是!

    我们刚才说过,cookies是在客户端产生,也就是我们自己的电脑上保存的

    另一方面,Main.aspx这个页面判断 你是否能够访问的依据就是 cookies中的值是多少,如果是1,则认为你当前身份是UID为1的用户,如果是5,则认为你当前身份是UID为5的用户。

    那么我们考虑一个事情,如果把我的cookies中的UID修改掉,比如改成35,是不是可以直接绕过登录页面,就可以以UID为35的用户身份登录呢?

    事实上确实是这样,这也就是标题中所说的cookies欺骗。由于cookies是客户端产生我们可以很容易的修改,因此产生安全隐患。

    下面就来实际测试一下,首先下载一款软件 老兵cookies欺骗工具 界面如下图:

    在Address中输入我们项目的访问地址,然后连接

    然后正常操作一遍,分别点击 获取登录状态  和  未获取登录状态

       

    发现我们正常操作是正常的判断,下面重点来了,我们要修改cookies值 点击未获取登录状态 一样可以被授权访问

     

    登录成功了,那么我们应该如何避免这样的问题呢?

    正确的做法是,把密码同时存入cookies(当然实际操作时候需要MD5加密保存,这里为了方面演示使用明文保存),然后在Main.aspx验证时候,同时验证UID和密码是否匹配即可。

    我们来修改一下代码:

    Login页面

     1 protected void Page_Load(object sender, EventArgs e)
     2     {
     3         //每次加载登录页面 清理UID 清除登录状态
     4         Response.Cookies["uid"].Value = "0";
     5         Response.Cookies["pwd"].Value = "";
     6     }
     7     protected void Button1_Click(object sender, EventArgs e)
     8     {
     9         //验证步骤略过,假设用户通过验证并且得到如下信息:
    10 
    11         int uid = 1; //用户唯一ID
    12         string username = "admin"; //用户名
    13         string userpwd = "123456"; //用户密码
    14 
    15         //接下来要保存用户登录状态
    16         Response.Cookies["uid"].Value = uid.ToString();
    17         Response.Cookies["pwd"].Value = userpwd;
    18         //跳转到登录后的页面
    19         Response.Redirect("Main.aspx");
    20 
    21     }
    22     protected void Button2_Click(object sender, EventArgs e)
    23     {
    24         //未经验证直接进入Main.aspx
    25         Response.Redirect("Main.aspx");
    26     }

    Main页面

     1 private void CheckLogin()
     2     {
     3         if (Request.Cookies["uid"] != null && Request.Cookies["pwd"] != null && GetUserInfo(int.Parse(Request.Cookies["uid"].Value), "") != "")
     4         {
     5             if (Request.Cookies["pwd"].Value == GetUserInfo(int.Parse(Request.Cookies["uid"].Value), "password"))
     6             {
     7                 Response.Write(GetUserInfo(int.Parse(Request.Cookies["uid"].Value), "username") + "已登录");
     8             }
     9             else
    10             {
    11                 Response.Write("您尚未登陆,<a href='login.aspx'>点此登录</a>");
    12             }
    13         }
    14         else
    15         {
    16             Response.Write("您尚未登陆,<a href='login.aspx'>点此登录</a>");
    17         }
    18     }

    这样改动之后,用户如果再以修改cookies企图绕过验证的话,那么他除了修改UID之外,还必须修改pwd为正确的密码。

    有同学问:那如果他就是把PWD改成正确的密码了呢?

    这位同学...你的密码都别别人窃取了...那么再安全的程序代码也救不了你....

    本文中案例源码及相关工具下载:http://files.cnblogs.com/webconfig/Cookies%E6%AC%BA%E9%AA%97.rar

    感谢小伙伴们的热烈讨论,按照 @老牛吃肉 和其他同类观点的用户的建议,我尝试做了另一方案,做下补充。

    使用DES把UID加密放在cookies中,在验证阶段解密验证。

    http://www.cnblogs.com/webconfig/p/3624831.html

    本文出自 低调码农的笔记簿 http://www.cnblogs.com/webconfig/p/3623343.html 转载请注明出处,如有谬误不当之处,欢迎指正拍砖,不胜感谢!!

  • 相关阅读:
    ubuntu 12.04下 eclipse的安装
    ubuntu 12.04下 ns3的下载 安装
    win10下装上virtualbox 以及在virtualbox上装上 ubuntu 12.04
    Java并发,synchronized锁住的内容
    JVM深入理解
    华为面试流程
    eclipse将项目打包成jar在linux中运行
    1.整数反转
    静态方法
    java中生成任意之间数的随机数
  • 原文地址:https://www.cnblogs.com/webconfig/p/3623343.html
Copyright © 2011-2022 走看看