Reflection带来的潜在威胁 - 应付探讨
2004-09-10 12:12
381 查看
我在前一篇文章(Reflection带来的潜在威胁)中提到了通过Reflection访问private member所带来后果,这里接着这个话题来讨论应付这一问题的方法!
方法一:毫无疑问,那就是尽量不要把机密的代码发布出去。这也是最可靠的方法,然而很多情况下,我们做不到这一点,遇到这种情况我们也只好继续寻求其他解决方式……
方法二:通过制定StrongNameIdentityPermissionAttribute(感谢hBifTs提供的文章)来限制调用者的范围,如下所示:
[StrongNameIdentityPermissionAttribute(SecurityAction.Demand, PublicKey="002400000...")]
private static string Decrypt(byte[] d)
{
}
这时直接访问的话,runtime会扔出SecurityException。但遗憾的是,调用者可以在调用前通过如下语句关闭安全检查:
SecurityManager.SecurityEnabled = false;
这样一来,我们的安全设置依然形同虚设。根据这种方法的原理--检查被调用者的身份,我想到了下面方法:
方法三:在System.Diagnostics名字空间下有一个StackTrace的东东(我前不久刚用它写了一个写日志时详细记录Stack的辅助类,过两天我会把这个东东也Post上来 -- 哈哈,做了一次广告!),有了它,我们便可以得到调用者的信息,然后……好,废话少说,看看代码就知道了:
private static string Decrypt(byte[] d)
{
CheckCaller("SecLib, Version=1.0.1713.28332, Culture=neutral, PublicKeyToken=null");
...
}
private static void CheckCaller(string fullName)
{
StackTrace st = new StackTrace(2, false);
StackFrame sf = st.GetFrame(0);
MethodBase mb = sf.GetMethod();
if(mb.DeclaringType.Assembly.FullName != fullName)
throw new Exception("Invalid caller!");
}
这样我们便相当于自己强制做了一次调用者身份检查,而这一检查显然不会受系统的安全设置的影响。我这里使用Assembly.FullName来判断调用者是否合法,当然你完全可以使用别的逻辑,比如判断调用者是否是通过Reflection方式等等。
最后总结一下,方法一无疑是最可靠的,因此能遵循就尽量遵循。方法二无法起到保护作用,这里列出来只是表明方法三的思路来源于前者。方法三能基本达到我们的目的,但有许多局限性,如:别人依然可以通过Reflection看到我们的代码(用人说发布前使用混淆器,当然可以,不过保护代码不是本文关心的事情);或者运用各种手段跳过我们的检查……没有办法,既然你要在大街上走,就无法完全避免被人偷拍:)
下载该例子的完整代码:ReflectionTrap1.zip
方法一:毫无疑问,那就是尽量不要把机密的代码发布出去。这也是最可靠的方法,然而很多情况下,我们做不到这一点,遇到这种情况我们也只好继续寻求其他解决方式……
方法二:通过制定StrongNameIdentityPermissionAttribute(感谢hBifTs提供的文章)来限制调用者的范围,如下所示:
[StrongNameIdentityPermissionAttribute(SecurityAction.Demand, PublicKey="002400000...")]
private static string Decrypt(byte[] d)
{
}
这时直接访问的话,runtime会扔出SecurityException。但遗憾的是,调用者可以在调用前通过如下语句关闭安全检查:
SecurityManager.SecurityEnabled = false;
这样一来,我们的安全设置依然形同虚设。根据这种方法的原理--检查被调用者的身份,我想到了下面方法:
方法三:在System.Diagnostics名字空间下有一个StackTrace的东东(我前不久刚用它写了一个写日志时详细记录Stack的辅助类,过两天我会把这个东东也Post上来 -- 哈哈,做了一次广告!),有了它,我们便可以得到调用者的信息,然后……好,废话少说,看看代码就知道了:
private static string Decrypt(byte[] d)
{
CheckCaller("SecLib, Version=1.0.1713.28332, Culture=neutral, PublicKeyToken=null");
...
}
private static void CheckCaller(string fullName)
{
StackTrace st = new StackTrace(2, false);
StackFrame sf = st.GetFrame(0);
MethodBase mb = sf.GetMethod();
if(mb.DeclaringType.Assembly.FullName != fullName)
throw new Exception("Invalid caller!");
}
这样我们便相当于自己强制做了一次调用者身份检查,而这一检查显然不会受系统的安全设置的影响。我这里使用Assembly.FullName来判断调用者是否合法,当然你完全可以使用别的逻辑,比如判断调用者是否是通过Reflection方式等等。
最后总结一下,方法一无疑是最可靠的,因此能遵循就尽量遵循。方法二无法起到保护作用,这里列出来只是表明方法三的思路来源于前者。方法三能基本达到我们的目的,但有许多局限性,如:别人依然可以通过Reflection看到我们的代码(用人说发布前使用混淆器,当然可以,不过保护代码不是本文关心的事情);或者运用各种手段跳过我们的检查……没有办法,既然你要在大街上走,就无法完全避免被人偷拍:)
下载该例子的完整代码:ReflectionTrap1.zip
相关文章推荐
- Reflection带来的潜在威胁
- 探讨工作流能给公司带来的几点益处
- 卫星地图遭遇互联网 带来潜在广告市场 zz
- 企业如何预防「意外掉电」带来的数据安全威胁?
- 互联网究竟带来中心化还是去中心化 那些赚钱的模式 探讨下互联网会把社会改造成什么样子,到底是中心化还是去中心化
- 打印机扫描仪等嵌入式Web服务存在潜在威胁
- 潜在的威胁——构造器内的多态方法行为
- 移动办公带来的潜在安全风险
- 潜在威胁的识别
- 配置内存作祟 PC硬件组件恐带来rootkit威胁
- 苹果是不是低估了三星所带来的威胁?
- Python中eval带来的潜在风险
- 路由器,交换机中的潜在的安全威胁
- 历史版本兼容问题 - 使用枚举值带来的潜在风险
- 潜在威胁 云计算将使技术性工作消失?
- 数据的几个潜在的威胁
- 三个应用案例——大数据挖掘潜在的威胁
- Python中eval带来的潜在风险代码分析
- 招股书显示Facebook四大潜在威胁:谷歌居首
- 减少Java安全更新 带来的潜在风险