I’m working on an application that loads untrusted assemblies via an interface. Each of those assemblies should be able to add one or more GameAction objects to a thread-safe queue used by the server.
The first iteration of design was to just pass the queue–something like this:
public interface IGameClient { void HandleStateChange(IGameState gameState, ref Queue<IGameAction> actionQueue); }
But, the problem with this is that it gives an untrusted assembly access to a shared queue, allowing it to manipulate other members of the queue and discover information about other queue actions.
The second pass was:
public interface IGameClient { void HandleStateChange(IGameState gameState); GameActionDelegate event HasNewEvent; // passes IGameAction as a parameter }
The problem with this is that it doesn’t necessarily allow for the ordering or grouping of actions.
What I’m really hoping for is to be able to pass a reference to an object that encapsulates the thread-safe queue, but only exposes Enqueue(). But, I’m afraid that an untrusted assembly could manipulate a private Queue object using reflection.
So, what’s the best way to handle this?
Thoughts in no particular order:
1) Events do guarantee ordering (or at least, your implementation could guarantee whatever ordering you want, and the simplest implementations will preserve ordering).
2) I don’t see why you’d want to pass the queue by reference in the first example of the interface. It may be worth checking that you understand parameter passing and ‘ref’.
3) If you come up with an interface which only exposes Enqueue then the implementation presumably won’t be a
Queue<T>. It might contain aQueue<T>, but if you really don’t trust assemblies not to mess around with your private members, you should load them in such a way that you don’t grant them the relevant reflection permissions.Another alternative might be to pass in an
Action<IGameAction>which the client can call when it wants to add an item to the queue. The delegate would be created from whatever Enqueue method you’ve got.