<转>水平权限漏洞的防护功能实现
先前曾发表过一遍介绍水平权限漏洞的文章:
水平权限漏洞的修复方案:http://www.cnblogs.com/hnsongbiao/p/3752617.html
"水平权限漏洞一般出现在一个用户对象关联多个其他对象(订单、地址等)、并且 要实现对关联对象的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 }
可以看到,在加密和解密方法中,我使用了用户的密码作为秘钥,这样对水平权限漏洞的预防会更好。
通用权限底层对安全防护做的很完美,大家合理利用,可预防常见安全问题的产生。
对于水平权限漏洞的预防,大家如果有更好的方法,欢迎交流~~,上面提供的底层方法,大家可以直接在项目中使用。
posted on 2015-10-31 00:17 hahahahahai12 阅读(281) 评论(0) 收藏 举报

浙公网安备 33010602011771号