访问级别和修饰符(私有、密封等)在 C# 中是否具有安全目的?
我发现您可以使用反射来操作私有和内部成员。 我还看到它说 “密封”类比非密封类更安全< /a>.
修饰符“public、protected、internal、private、abstract、sealed、readonly”是否只是关于设计和 API 使用的君子协议,只要您有权访问反射就可以打破? 如果黑客已经在运行调用您的 API 的代码,那么游戏就已经失败了,对吧?
下面的类比其他类更安全吗?
//private class
sealed class User
{
private string _secret = "shazam";
public readonly decimal YourSalary;
public string YourOffice{get;};
private DoPrivilegedAction()
{
}
}
I've seen that you can manipulate private and internal members using reflection. I've also seen it said that a 'sealed' class is more secure that one that isn't.
Are the modifiers "public, protected, internal, private, abstract, sealed, readonly" anything more than a gentleman's agreement about design and API use, that can be broken as long as you have access to reflection? And if a hacker is already is running code that calls your API, the game is already lost, right?
Is the following anymore secure than any other class?
//private class
sealed class User
{
private string _secret = "shazam";
public readonly decimal YourSalary;
public string YourOffice{get;};
private DoPrivilegedAction()
{
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,回答您的问题:安全系统旨在保护好用户免受坏代码的侵害; 它显然不是为了保护良好的代码免受不良用户的侵害而设计的。 您的访问限制可以减轻部分受信任的恶意代码对用户的攻击。 它们不会减轻来自敌意用户的对代码的攻击。 如果威胁是敌对用户获取您的代码,那么您就有大问题了。 安全系统根本无法减轻这种威胁。
其次,解决之前的一些答案:理解反射和安全之间的完整关系需要仔细关注细节并充分理解 CAS 系统的细节。 之前发布的答案指出,由于反射,安全性和访问之间没有联系,这是误导和错误的。
是的,反射允许您覆盖“可见性”限制(有时)。 这并不意味着访问和安全之间没有联系。 连接之处在于,使用反射来覆盖访问限制的权利以多种方式与 CAS 系统紧密相连。
首先,为了任意执行此操作,CAS 系统必须向代码授予私有反射权限。 这通常只授予完全可信的代码,毕竟它已经可以做任何事情了。
其次,在新的 .NET 安全模型中,假设 CAS 系统授予程序集 A 的授权集是程序集 B 的授权集的超集。 在这种情况下,程序集 A 中的代码可以使用反射来观察 B 的内部结构。
第三,当您将动态生成的代码放入其中时,事情变得非常复杂。 解释“跳过可见性”与“受限跳过可见性”的工作原理,以及它们如何在运行时吐出代码的情况下改变反射、访问控制和安全系统之间的交互,将花费我更多的时间和空间。有可用的。 如果您需要详细信息,请参阅 Shawn Farkas 的博客。
First, to answer your question: The security system is designed to protect GOOD USERS from BAD CODE; it is explicitly not designed to protect GOOD CODE from BAD USERS. Your access restrictions mitigate attacks on your users by partially trusted hostile code. They do not mitigate attacks on your code from hostile users. If the threat is hostile users getting your code, then you have a big problem. The security system does not mitigate that threat at all.
Second, to address some of the previous answers: understanding the full relationship between reflection and security requires careful attention to detail and a good understanding of the details of the CAS system. The previously posted answers which state that there is no connection between security and access because of reflection are misleading and wrong.
Yes, reflection allows you to override "visibility" restrictions (sometimes). That does not imply that there is no connection between access and security. The connection is that the right to use reflection to override access restrictions is deeply connected to the CAS system in multiple ways.
First off, in order to do so arbitrarily, code must be granted private reflection permission by the CAS system. This is typically only granted to fully trusted code, which, after all, could already do anything.
Second, in the new .NET security model, suppose assembly A is granted a superset of the grant set of assembly B by the CAS system. In this scenario, code in assembly A is allowed to use reflection to observe B's internals.
Third, things get really quite complicated when you throw in dynamically generated code into the mix. An explanation of how "Skip Visibility" vs "Restricted Skip Visibility" works, and how they change the interactions between reflection, access control, and the security system in scenarios where code is being spit at runtime would take me more time and space than I have available. See Shawn Farkas's blog if you need details.
访问修饰符与安全性无关,而是与良好的设计有关。 类和方法的适当访问级别驱动/强制执行良好的设计原则。 理想情况下,只有当使用反射的便利性比违反(如果有的话)最佳设计实践的成本更多时才应使用反射。 密封类的目的只是为了防止开发人员扩展您的类并“破坏”它的功能。 关于密封类的实用性有不同的观点,但由于我进行 TDD 并且很难模拟密封类,所以我尽可能避免它。
如果您想要安全,则需要遵循编码实践,以防止坏人进入和/或保护机密信息免遭检查,即使发生入侵也是如此。 入侵防御、入侵检测、加密、审计等是您需要使用的一些工具来保护您的应用程序。 在我看来,设置限制性访问修饰符和密封类与应用程序安全性关系不大。
Access modifiers aren't about security, but good design. Proper access levels for classes and methods drives/enforces good design principles. Reflection should, ideally, only be used when the convenience of using it provides more utility than the cost of violating (if there is one) best design practices. Sealing classes only serves the purpose of preventing developers from extending your class and "breaking" it's functionality. There are different opinions on the utility of sealing classes, but since I do TDD and it's hard to mock a sealed class, I avoid it as much as possible.
If you want security, you need to follow coding practices that prevent the bad guys from getting in and/or protect confidential information from inspection even if a break in occurs. Intrusion prevention, intrusion detection, encryption, auditing, etc. are some of the tools that you need to employ to secure your application. Setting up restrictive access modifiers and sealing classes has little to do with application security, IMO.
不,这些与安全无关。 反思打破了这一切。
No. These have nothing to do with security. Reflection breaks them all.
关于反射和安全性的评论 - 考虑到 mscorlib.dll 中有许多内部类型 + 成员调用本机 Windows 函数,如果恶意应用程序使用反射调用它们,则可能会导致不良后果。 这不一定是问题,因为运行时通常不会向不受信任的应用程序授予这些权限。 这(以及一些声明性安全检查)是 mscorlib.dll 二进制文件如何将其类型公开给各种受信任和不受信任的代码,但不受信任的代码无法绕过公共 API。
这实际上只是触及了反射+安全问题的表面,但希望它有足够的信息来引导您走上正确的道路。
Regarding the comments about reflection and security - consider that there are many internal types + members in mscorlib.dll that call into native Windows functions and can potentially lead to badness if a malicious application uses reflection to call into them. This isn't necessarily a problem since untrusted applications normally aren't granted these permissions by the runtime. This (and a few declarative security checks) is how the mscorlib.dll binary can expose its types to all manner of trusted and untrusted code, yet the untrusted code can't get around the public API.
This is really just scratching the surface of the reflection + security issue, but hopefully it's enough information to lead you down the right path.
我总是尝试将事情限制在所需的最低限度。 正如 tvanfosson 所说,这实际上更多的是设计而不是安全。
例如,我将公开一个接口,将我的实现公开,然后公开一个工厂类/方法来获取实现。 这几乎迫使消费者始终将其键入为接口,而不是实现。
话虽这么说,开发人员可以使用反射来实际实例化实现类型的新实例。 没有什么可以阻止他/她。 然而,我可以放心,我知道我至少让违反设计变得有些困难。
I always try to lock things down to the minimal access required. Like tvanfosson stated, it's really about design more than security.
For example, I'll make an interface public, and my implementations internal, and then a public factory class/methods to get the implementations. This pretty much forces the consumers to always type it as the interface, and not the implementation.
That being said, a developer could use reflection to actually instantiate a new instance of an implementation type. There's nothing stopping him/her. However, I can rest knowing that I made it at least somewhat difficult to violate the design.