I have an application domain to host untrusted code/assembly. I solved all problems with security with security attributes and it works well. The untrusted code runs on dedicated thread. CLR is 2.0. This is what I have AppDomainShell AppDomainSeed, Shell is running in main domain, seed is trusted proxy/helper in untrusted domain.
I'm interested to restrict creating new threads and changing priority. At the moment my untrusted assembly could set ThreadPriority.Highest or kill operating system by creating 10k threads. There is SecurityPermissionFlag.ControlThread but that prevents just from advanced operations like Abort().
I was looking at Thread class implementation and there is no declarative security on C# API of it for those simple operations, rest of the implementation is native.
I guess I could use some Win32 functions to ban that on OS level. But how operating system recognizes the thread/code/assembly which is not trusted? SetThreadPrincipal() ?
Is there any API of CLR which could be abused ? I prefer solution without need for installation and portable to Mono, :-/ hmmm.
Any other ideas welcome. Thanks!
I'm considering another solution. Static analysis of CIL of untrusted assembly.
I could search thru all methods, properties, constructors. Recognize references to types. If I found reference to Thread type, I throw security exception and unload assembly.
I quite like work of Jb Evain. He created Mono Cecil, but that's quite heavyweight. He also drafted CIL reader, just with .NET reflection.
I created Linq over reflection using CIL Reader. Usage look like this.
var myAssembly = typeof (Program).Assembly;
foreach (Type usedType in myAssembly.GetUsedTypes())
{
if (typeof (Thread).IsAssignableFrom(usedType) ||
typeof (ThreadPool).IsAssignableFrom(usedType) ||
typeof (ThreadPriority).IsAssignableFrom(usedType)
)
{
throw new SecurityException("Thread usage is banned here!");
}
}
Threads run within a single process, and you should be safe as your untrusted code can't change the priority of the process. (See MSDN here for details.)
I'm not sure that even creating 10k threads within a process would necessarily kill Windows - at least, not any version of Windows above Windows NT. Your process would almost certainly stop running, however, so you might want to consider two processes and use a mechanism such as remoting or WCF to communciate between them.
Maybe HostProtectionAttribute is the right thing for limiting thread manipulation by untrusted code?