No Security Hole - Just a Hideous Idea
on
Hijacking .NET
·
· Score: 2, Informative
First, let me say I have not read the ebook - just the abstract. I'm assuming it uses either Reflection or some technique that uses unverifiable code (which essentially means it can own your machine if you allow it to run).
As many people have already pointed out, this is not a security hole in the.NET Framework. Member visibility is a statement about what you intend to support and document, but is not strictly a statement of security. Additionally, the.NET Framework security model prohibits code like this from running, depending on security policy and where the code comes from.
That being said, let me show how this can be done, and how using code access security, you can prevent this. Note that the default policies for code from the Internet and Intranet zones will not allow this code to run.
Note that if you want to prevent member access, the.NET Framework does provide a way to do this, unlike other runtime environments or languages like Java or C++. Look at the strong name identity permission in the MSDN documentation or a great security book for more details.
As many have already pointed out, calling someone else's internal member is an excellent way of making your application fragile and adding a source of potentially incorrect behavior. There's no guarantee that someone else's private members will be there or work the same way in a future version (including a service pack) - that's why they're private.
The author's point of using P/Invoke declarations from the.NET Framework is also a very bad one, since they may change with no notice. For instance, any P/Invoke method that uses a handle may have accidentally used an Int32 for the handle type in V1. In V1.1, it might use a IntPtr, while in V2.0 it will likely use a subclass of SafeHandle, a new handle wrapper that doesn't exist in released versions.
About the only good reason to use Reflection to call private members is for hiding details of a Reflection-based set of functionality where the details of a particular implementation aren't interesting to users. An example would be TypeConverters. Here there's a general design pattern and you may write a TypeConverter for your type, yet you could mark it private if it is really not worth seeing in an object browser or Intellisense. Using Reflection, an instance of this class could be created. However, this isn't a generally recomended technique.
With this being said, here's an example of how to use Reflection to call private members, and shows that the.NET Framework does indeed do a security check here. This app should run correctly if you run it locally if you haven't modified your machine's security policy, but if it is run over a network share, it will fail.
using System; using System.Reflection; using System.Security.Permissions; using System.Security;
public sealed class MyPublicClass {
private static int PrivateFoo()
{
return 5;
} }
public sealed class CallPrivateMemberTest {
private static void CallPrivateMember()
{ // Remember that calling private members is a good way of building // an incredibly brittle application. This is a hideously bad idea, // outside of some well-constrained scenarios. And of course, you // can use strong name identity permission to prevent people from // calling private methods like this.
Type type = typeof(MyPublicClass);
MethodInfo mi = type.GetMethod("PrivateFoo", BindingFlags.Static | BindingFlags.NonPublic);
Object retVal = mi.Invoke(null, BindingFlags.Static | BindingFlags.NonPublic, null, null, null);
Console.WriteLine("Called private method. It returned: {0} [{1}
As many people have already pointed out, this is not a security hole in the
That being said, let me show how this can be done, and how using code access security, you can prevent this. Note that the default policies for code from the Internet and Intranet zones will not allow this code to run.
Note that if you want to prevent member access, the
As many have already pointed out, calling someone else's internal member is an excellent way of making your application fragile and adding a source of potentially incorrect behavior. There's no guarantee that someone else's private members will be there or work the same way in a future version (including a service pack) - that's why they're private.
The author's point of using P/Invoke declarations from the
About the only good reason to use Reflection to call private members is for hiding details of a Reflection-based set of functionality where the details of a particular implementation aren't interesting to users. An example would be TypeConverters. Here there's a general design pattern and you may write a TypeConverter for your type, yet you could mark it private if it is really not worth seeing in an object browser or Intellisense. Using Reflection, an instance of this class could be created. However, this isn't a generally recomended technique.
With this being said, here's an example of how to use Reflection to call private members, and shows that the