Cookies欺騙分析與防禦

今天來談談cookies欺騙是怎麼回事以及如何避免。html

用戶在登陸以後一般會保存用戶信息,以便在其餘須要權限的頁面去驗證用戶信息是否具備訪問權限。web

有同窗說我在登陸的時候已經很注意SQL注入問題了,還有什麼不安全的地方麼?數據庫

固然有!這個要首先談一個問題,那就是用戶身份驗證的流程 以下圖:瀏覽器

 

所以咱們能夠看出,一個頁面是否可以被訪問,判斷依據是經過存儲信息區域中用戶的信息來判斷的安全

而登陸頁面的做用就是 驗證 用戶輸入的用戶名+密碼的組合是否在數據庫中存在,若是存在則把信息保存在存儲信息的區域,以便各個頁面去判斷權限服務器

OK,理清這個思路以後咱們的重點就來了,那個信息存儲區域對於咱們來講相當重要,通常常見的有兩種形式,session和cookiescookie

 

session和cookies一樣都是針對單獨用戶的變量(或者說是對象好像更合適點),不一樣的用戶在訪問網站的時候 都會擁有各自的session或者cookies,不一樣用戶之間互不干擾。session

他們的不一樣點是:工具

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 轉載請註明出處,若有謬誤不當之處,歡迎指正拍磚,不勝感謝!!

相關文章
相關標籤/搜索