views:

643

answers:

11

Hi Guys

I have a very interesting situation , i have figured out that Singleton pattern is not all possible with .net framework (Any version)

look at this code below

namespace SingletonPattern
{
    class Singleton
    {
    private static readonly Singleton instance = new Singleton();
    private static int mcount = 0;

    private Singleton() {

        mcount += 1;
        Console.WriteLine("Creating {0} instances of Singleton Class", mcount.ToString());
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

class program
{
    static void Main()
    {
        for (int i = 0; i < 1000; i++)
        {
            System.Activator.CreateInstance(Type.GetType("SingletonPattern.Singleton"), true);
        }

        Console.ReadLine();


        }
    }
}

with the help of System.activator any buddy can break singleton pattern.

so who's at risk ?

any guy who wrote some licensing component where license is implemented as a singleton pattern.

Any server based code which makes use of Singleton pattern.

Maybe I am wrong or my discovery does not make sense but i just wanna share and want to know your views?

+11  A: 

It is true that this implementation of a singleton is wrong, but that doesn't mean that someone couldn't create a better singleton implementation.

Andrew Hare
For a good discussion about a useful singleton pattern have a look at http://yoda.arachsys.com/csharp/singleton.html
tanascius
@tanascius Thanks for the link.
Jason Down
+8  A: 

By the same token, all private methods are not private because you can access them using reflection.

I don't see a problem with this.

DarenFox
+24  A: 

Just because it is possible to deliberately circumvent a pattern in this way does not mean that the pattern itself is "not possible".

Dale Halliwell
Actually, this guy has a point. If you have valid reasons to create a singleton (for whatever reason you only want 1 of your class in existence), then you can just use Activator.CreateInstance anytime you want a copy (overriding your Singleton
RCIX
A: 

it's System.Activator class which is not foolproof, i guess and can create hazards thfor a application , i wonder why Microsoft does not think about this.

Saurabh
What are they supposed to do about it? It is only a hazard if someone deliberately *intend* to break your singleton, and if they do that, they probably have a reason. What's the harm?
jalf
@Dale Halliwell: no call for that. Flagged as offensive
jalf
I don't mean to come off as a jerk with that comment, I just really think you need to reexamine what design patterns are and what they are used for. Especially before assigning blame to Microsoft or anyone else, or declaring the Singleton pattern in the .NET framework "not possible", because that is just going to irritate people.
Dale Halliwell
Not only wasn't the comment good, but the downvote wasn't either. He ASKED for input and views, you don't have to crap on him, just educate him.
Lance Roberts
i think , i posted wrong question Guys but if my code runs under high previged mode than some time it can be broken.
Saurabh
+4  A: 

To use System.Activator.CreateInstance, you need high permissions. Of course if you're allowed to ignore access modifiers because the system trusts you, then you can break code that depends on consumers respecting access modifiers.

Normally, code does not usually have these permissions.

Joren
Exactly. If you grant code permission to do something, then you can't complain about the fact that it has permission to do it.
Greg Beech
+1  A: 

if you want to protect against this edge case just change private ctor:

private Singleton() { throw new ApplicationException{
     "Don't call System.Activator.CreateInstance on this class"); }

And then you'll then have to add another parameterized private ctor to actually create the singleton... perhaps with a secret parameter that only the initalizer will know how to pass... entire class would be:

class Singleton
{    
   private static readonly Singleton inst = new Singleton("MySecretWord");    
   private static int mcount = 0;   
   private Singleton(string secret)
   { if (secret != "MySecretWord")  
       throw new ApplicationException{
           "Don't call Private constructor on this class"); 
   }
   private Singleton() { throw new ApplicationException{
     "Don't call System.Activator.CreateInstance on this class"); }
  public static Singleton Instance { get  {  return inst ;  } }
}

But why go to all this trouble ? if someone wants to go to the trouble to break your singleton pattern using CreateInstance, then that's there problem, no?

Charles Bretana
Erm, sorry if im being stupid, but that wouldnt work as the private constructor needs to be called.
DarenFox
@darren, editing while you commented, to add exactly that point!
Charles Bretana
And even then they could just use a tool like reflector to find your secret word..
markt
@markt, wouldn't CreateInstance have to be recoded in the CLR framework to even CALL the parameterized private ctor?
Charles Bretana
Probably you are correct -- I didn't realize that you could only call parameterless private constructors with CreateInstance.. interesting.
markt
@Marky, I'm not sure either, but as I would guess, CreateInstance, which is in mscorlib.dll, must call the default or explicit private parameterless ctor using the elevated privileges available to code running inside the CLR... but, again afaik, I don't see any mechanism available to allow client code to specify that it should call a different ctor that takes a paramater...
Charles Bretana
A: 

If you are concerned about other code attempting to break this pattern, you could use something like a lock, or a semaphore or mutex,etc.. in your implementation to manage the number of instances.

...which might end up making it just a little bit more difficult, as reflection may still be used again to circumvent this...

But - with a locking mechanism, you will take a performance hit, so you have weigh the benefits..

markt
+3  A: 

I don't think design patterns are a form of security as much as a way to encourage a certain usage. If someone is going to that much trouble to work around the constraints of your design, they get what they deserve.

JohnFx
A: 

but Dale if my code is weak enough {it is not tracking the no of instances of the class.} than most of the implementations can be broken.

Saurabh
+1  A: 

Every client-side licensing scheme can be broken.

You could work around this by throwing an exception if the counter is greater 1 - but then again, the other code could use Reflection to reset the counter. The calling code could even modify your assembly before loading it, completely removing the licensing code!

No programming language, obfuscator, etc. can completely protect you against this - if it was possible, surely game publishers would have already used it to create unbreakable copy protection!

As soon as you've got untrusted code in the same 'security zone' as your code; you've already lost.

Daniel
+1  A: 

Thanks Guys

For the responses and i found that .net framework is having best design and code should enforce Code Access Security whenever possible.

Write Secure Code.

Regards Saurabh

Saurabh