SECURITY is a singleton, right? (Or do you have one per PLUGIN type? Not sure it matters.)
I think the answer lies in giving each plugin a "cookie" that it has to use in order to make calls; if the cookie values can't be faked, I think you're safe. Details: SECURITY is (or should be) responsible for creating the PLUGIN instances. Each PLUGIN class has an Identity property (a read-only string, but the read-only is not important to the security [as it's bogus]). When SECURITY creates a PLUGIN, it assigns an essentially arbitrary (unpredictable) value to the Identity property. The methods of SECURITY that PLUGINs can call each require a valid Identity value to be passed in. Information about the PLUGINs is recorded in a SECURITY-owned HashTable with the Identity values as the key. The corresponding objects stored in the HashTable include a field that holds a reference to the PLUGIN that has the matching Identity. If a call to SECURITY is made that has a not-present Identity value, someone is trying to break security (or has buggy code). If more than N bad calls are made, any PLUGIN of that type is shut down when it next makes a call. (Each PLUGIN-callable SECURITY method must have a result value that indicates "you are no longer a valid instance; good night.") If you use a cryptographically strong mechanism to generate the Identity values, you're pretty safe. One semi-flaw is that a PLUGIN that's trying to break in (by passing a bunch of fake Identity values, one of which it hopes will identify another active PLUGIN) could cause a Denial Of Service if you implement the "shut down all PLUGINs of that type" protection mechanism above. But if the source code for the PLUGIN is in your hands, a human being could figure out what's going on -- it's not just anyone that can ask for a new PLUGIN type to be created, right? That is, you would know who wanted to build a PLUGIN that was being naughty and could take appropriate non-computer-related action. Good luck. At 02:16 PM 8/21/2003 -0400, Janis Braslins wrote >I am in a bit of a bind here. If you have a few minutes, perhaps you could >help me out with this architecture design issue. > > >SPEC: > >1) We have a central object/assembly that has permissions to access certain >elements that no other object of the application can. We call it SECURITY >object. > >2) We have numerous objects compiled and invoked at runtime that will be >performing calls to the SECURITY object. We refer to them as PLUGINS. The >source of every PLUGIN is assumed to be "unsafe". When each PLUGIN is >compiled into assembly, it's FileIO/Registry and other sensitive >permissions are being refused. The intention is to let the PLUGINS access >sensitive information via SECURITY object. > >3) SECURITY object is tasked with compilation of PLUGINS at runtime. It's >important to note that multiple instances of the same PLUGIN will be able >to coexist at the same time and operate independently. > >4) When an instance of a compiled PLUGIN is being created, SECURITY object >must assign it a certain role based on numerous external parameters not >contained within the PLUGIN source. Those roles determine what functions of >the SECURITY object those PLUGINS have access to. > >5) The PLUGINS themselves should not be capable of changing their roles. > >6) SECURITY object should be able to change the role of a certain >_instance_ of a PLUGIN at runtime when some external conditions are met. > > >PROBLEMS: > >1) So, basically, we can't store the ROLE of the each instance of the >PLUGIN within the PLUGIN itself, as it would then be able to modify it's >own role. > >2) We cannot use declarative custom security permission checks to limit the >role each PLUGIN gets, as each instance of the PLUGIN can have a separate >role. > >3) We cannot use imperative custom security permission checks (I just don't >see how it would work, please correct me if I am wrong) > > >POSSIBLE SOLUTIONS: > >I've though of storing information regarding each instance of every PLUGIN >created and activated inside SECURITY object. But that means SECURITY >object should be aware of who the callers of it's methods are. > >We cannot require SECURITY object's methods to have a "caller" argument, as >PLUGINS would be able to obtain a reference to the other PLUGINS with >different roles, and pass those to the SECURITY object, faking their role. > >As far as I see, there's no way to obtain a reference to the caller object >via StackTrace/StackFrame classes, only reference to the caller type. Since >each instance of our PLUGIN can have a different role, that information is >not sufficient to determine callers role. > >I AM STUCK ... Ideas anyone? J. Merrill / Analytical Software Corp =================================== This list is hosted by DevelopMentorŪ http://www.develop.com NEW! ASP.NET courses you may be interested in: 2 Days of ASP.NET, 29 Sept 2003, in Redmond http://www.develop.com/courses/2daspdotnet Guerrilla ASP.NET, 13 Oct 2003, in Boston http://www.develop.com/courses/gaspdotnet View archives and manage your subscription(s) at http://discuss.develop.com