天天看點

水準權限漏洞的防護功能實作

先前曾發表過一遍介紹水準權限漏洞的文章:

水準權限漏洞的修複方案:​​javascript:void(0)​​

"水準權限漏洞一般出現在一個使用者對象關聯多個其他對象(訂單、位址等)、并且要實作對關聯對象的CRUD的時候。開發容易習慣性的在生成CRUD表單(或 AJAX請求)的時候根據認證過的使用者身份來找出其有權限的被操作對象id,提供入口,然後讓使用者送出請求,并根據這個id來操作相關對象。在處理 CRUD請求時,往往預設隻有有權限的使用者才能得到入口,進而才能操作相關對象,是以就不再校驗權限了。可悲劇的是大多數對象的ID都被設定為自增整型, 是以攻擊者隻要對相關id加1、減1、直至周遊,就可以操作其他使用者所關聯的對象了。"

該文章主要是對水準權限漏洞産生的原因進行了一些分析,感興趣的同學可以溫習下。

這次在一個安全項目開發中,上司要求預防水準權限漏洞的産生,項目底層正好使用了通用權限管理底層代碼。參考了上面文章的方法。

通過引用其底層代碼的安全工具類對水準權限漏洞進行了預防。下面把代碼分享下:

水準權限漏洞的防護功能實作

一、前端對userId,利用通用權限管理系統底層的方法DotNet.Utilities.SecretUtil.Encrypt方法加密。加密内部實作原理如下:

1         /// <summary>
 2         /// DES資料加密
 3         /// </summary>
 4         /// <param name="targetValue">目标值</param>
 5         /// <param name="key">密鑰</param>
 6         /// <returns>加密值</returns>
 7         public static string Encrypt(string targetValue, string key)
 8         {
 9             if (string.IsNullOrEmpty(targetValue))
10             {
11                 return string.Empty;
12             }
13 
14             var result = new StringBuilder();
15             var des = new DESCryptoServiceProvider();
16             byte[] inputByteArray = Encoding.Default.GetBytes(targetValue);
17             // 通過兩次哈希密碼設定對稱算法的初始化向量   
18             des.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile
19                                                   (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5").
20                                                        Substring(0, 8), "sha1").Substring(0, 8));
21             // 通過兩次哈希密碼設定算法的機密密鑰   
22             des.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile
23                                                  (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5")
24                                                       .Substring(0, 8), "md5").Substring(0, 8));
25             var ms = new MemoryStream();
26             var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
27             cs.Write(inputByteArray, 0, inputByteArray.Length);
28             cs.FlushFinalBlock();
29             foreach (byte b in ms.ToArray())
30             {
31                 result.AppendFormat("{0:X2}", b);
32             }
33             return result.ToString();
34         }      
水準權限漏洞的防護功能實作

二、背景利用通用權限管理系統底層的方法DotNet.Utilities.SecretUtil.Decrypt 對前台傳來的useId進行了解密,實作原理如下:

1         /// <summary>
 2         /// DES資料解密
 3         /// 20140219 吉日嘎拉 就是出錯了,也不能讓程式崩潰
 4         /// </summary>
 5         /// <param name="targetValue"></param>
 6         /// <param name="key"></param>
 7         /// <returns></returns>
 8         public static string Decrypt(string targetValue, string key)
 9         {
10             if (string.IsNullOrEmpty(targetValue))
11             {
12                 return string.Empty;
13             }
14             // 定義DES加密對象
15             try
16             {
17                 var des = new DESCryptoServiceProvider();
18                 int len = targetValue.Length / 2;
19                 var inputByteArray = new byte[len];
20                 int x, i;
21                 for (x = 0; x < len; x++)
22                 {
23                     i = Convert.ToInt32(targetValue.Substring(x * 2, 2), 16);
24                     inputByteArray[x] = (byte)i;
25                 }
26                 // 通過兩次哈希密碼設定對稱算法的初始化向量   
27                 des.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile
28                                                       (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5").
29                                                            Substring(0, 8), "sha1").Substring(0, 8));
30                 // 通過兩次哈希密碼設定算法的機密密鑰   
31                 des.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile
32                                                      (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5")
33                                                           .Substring(0, 8), "md5").Substring(0, 8));
34                 // 定義記憶體流
35                 var ms = new MemoryStream();
36                 // 定義加密流
37                 var cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
38                 cs.Write(inputByteArray, 0, inputByteArray.Length);
39                 cs.FlushFinalBlock();
40                 return Encoding.Default.GetString(ms.ToArray());
41             }
42             catch
43             {
44             }
45             return string.Empty;
46         }      

可以看到,在加密和解密方法中,我使用了使用者的密碼作為秘鑰,這樣對水準權限漏洞的預防會更好。

通用權限底層對安全防護做的很完美,大家合理利用,可預防常見安全問題的産生。

水準權限漏洞的防護功能實作

對于水準權限漏洞的預防,大家如果有更好的方法,歡迎交流~~,上面提供的底層方法,大家可以直接在項目中使用。