访问级别和修饰符(私有,密封等)是否在C#中起到安全作用?

时间:2022-09-02 10:50:45

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?

修饰语“公开,受保护,内部,私有,抽象,密封,只读”只不过是绅士关于设计和API使用的协议,只要您能够获得反思,就可以打破它们吗?如果一个黑客已经在运行调用你的API的代码,游戏就已经丢失了,对吧?

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()
    {
    }
}

5 个解决方案

#1


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.

其次,要解决以前的一些答案:理解反思和安全之间的完整关系需要仔细关注细节并充分理解CAS系统的细节。先前发布的答案表明,由于反射而在安全性和访问之间没有任何关联,这是错误的和错误的。

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.

是的,反射允许您覆盖“可见性”限制(有时)。这并不意味着访问和安全性之间没有联系。连接是使用反射来覆盖访问限制的权利以多种方式与CAS系统密切相关。

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.

首先,为了任意执行此操作,必须由CAS系统授予代码私有反射权限。这通常只授予完全受信任的代码,毕竟,这些代码已经可以执行任何操作。

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.

其次,在新的.NET安全模型中,假设程序集A被CAS系统授予程序集B的授权集的超集。在这种情况下,程序集A中的代码允许使用反射来观察B的内部。

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.

第三,当你将动态生成的代码投入到混合中时,事情变得非常复杂。解释“跳过可见性”与“限制跳过可见性”的工作方式,以及它们如何在运行时吐出代码的情况下改变反射,访问控制和安全系统之间的交互,这将比我花费更多的时间和空间有空的。如果您需要详细信息,请参阅Shawn Farkas的博客。

#2


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.

访问修饰符不是安全性,而是良好的设计。类和方法的适当访问级别驱动/强制执行良好的设计原则。理想情况下,只有在使用它的便利性提供比违反(如果有的话)最佳设计实践的成本更多的效用时,才应该使用反射。密封类仅用于防止开发人员扩展您的类并“破坏”它的功能。关于密封类的实用性有不同的意见,但由于我做TDD并且很难模拟密封类,我尽可能地避免它。

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.

如果您需要安全性,则需要遵循编码实践,以防止坏人进入和/或保护机密信息免于检查,即使发生中断。入侵防御,入侵检测,加密,审核等是您需要用来保护应用程序的一些工具。设置限制性访问修饰符和密封类与应用程序安全性IMO无关。

#3


No. These have nothing to do with security. Reflection breaks them all.

不,这些与安全无关。反思打破了他们所有。

#4


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.

关于反射和安全性的评论 - 考虑到mscorlib.dll中有许多内部类型+成员调用本机Windows函数,如果恶意应用程序使用反射来调用它们,则可能导致错误。这不一定是个问题,因为不受信任的应用程序通常不会被运行时授予这些权限。这(以及一些声明性安全检查)是mscorlib.dll二进制文件如何将其类型公开给所有受信任和不受信任的代码,但不受信任的代码无法绕过公共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.

这实际上只是触及反射+安全问题的表面,但希望它足以引导您走上正确的道路。

#5


I always try to lock things down to the minimal access required. Like tvanfosson stated, it's really about design more than security.

我总是试图将事情锁定到所需的最小访问权限。就像tvanfosson所说的那样,设计不仅仅是安全性。

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.

话虽这么说,开发人员可以使用反射来实际实例化实现类型的新实例。什么都没有阻止他/她。但是,我知道我至少在某种程度上难以违反设计。

#1


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.

其次,要解决以前的一些答案:理解反思和安全之间的完整关系需要仔细关注细节并充分理解CAS系统的细节。先前发布的答案表明,由于反射而在安全性和访问之间没有任何关联,这是错误的和错误的。

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.

是的,反射允许您覆盖“可见性”限制(有时)。这并不意味着访问和安全性之间没有联系。连接是使用反射来覆盖访问限制的权利以多种方式与CAS系统密切相关。

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.

首先,为了任意执行此操作,必须由CAS系统授予代码私有反射权限。这通常只授予完全受信任的代码,毕竟,这些代码已经可以执行任何操作。

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.

其次,在新的.NET安全模型中,假设程序集A被CAS系统授予程序集B的授权集的超集。在这种情况下,程序集A中的代码允许使用反射来观察B的内部。

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.

第三,当你将动态生成的代码投入到混合中时,事情变得非常复杂。解释“跳过可见性”与“限制跳过可见性”的工作方式,以及它们如何在运行时吐出代码的情况下改变反射,访问控制和安全系统之间的交互,这将比我花费更多的时间和空间有空的。如果您需要详细信息,请参阅Shawn Farkas的博客。

#2


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.

访问修饰符不是安全性,而是良好的设计。类和方法的适当访问级别驱动/强制执行良好的设计原则。理想情况下,只有在使用它的便利性提供比违反(如果有的话)最佳设计实践的成本更多的效用时,才应该使用反射。密封类仅用于防止开发人员扩展您的类并“破坏”它的功能。关于密封类的实用性有不同的意见,但由于我做TDD并且很难模拟密封类,我尽可能地避免它。

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.

如果您需要安全性,则需要遵循编码实践,以防止坏人进入和/或保护机密信息免于检查,即使发生中断。入侵防御,入侵检测,加密,审核等是您需要用来保护应用程序的一些工具。设置限制性访问修饰符和密封类与应用程序安全性IMO无关。

#3


No. These have nothing to do with security. Reflection breaks them all.

不,这些与安全无关。反思打破了他们所有。

#4


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.

关于反射和安全性的评论 - 考虑到mscorlib.dll中有许多内部类型+成员调用本机Windows函数,如果恶意应用程序使用反射来调用它们,则可能导致错误。这不一定是个问题,因为不受信任的应用程序通常不会被运行时授予这些权限。这(以及一些声明性安全检查)是mscorlib.dll二进制文件如何将其类型公开给所有受信任和不受信任的代码,但不受信任的代码无法绕过公共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.

这实际上只是触及反射+安全问题的表面,但希望它足以引导您走上正确的道路。

#5


I always try to lock things down to the minimal access required. Like tvanfosson stated, it's really about design more than security.

我总是试图将事情锁定到所需的最小访问权限。就像tvanfosson所说的那样,设计不仅仅是安全性。

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.

话虽这么说,开发人员可以使用反射来实际实例化实现类型的新实例。什么都没有阻止他/她。但是,我知道我至少在某种程度上难以违反设计。