标签:
先前曾发表过一遍介绍水平权限漏洞的文章:
水平权限漏洞的修复方案: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 }
可以看到,在加密和解密方法中,我使用了用户的密码作为秘钥,这样对水平权限漏洞的预防更好。
通用权限底层对安全防护做的很完美,大家合理利用,可预防常见安全问题的产生。
对于水平权限漏洞的预防,大家如果有更好的方法,欢迎交流~~,上面提供的底层方法,大家可以直接在项目中使用。
标签:
原文地址:http://www.cnblogs.com/hnsongbiao/p/4325120.html