Using whitelisting to run untrusted C# code safely

Started by
12 comments, last by WozNZ 8 years, 6 months ago

Could you please elaborate on what you are trying to protect, your application, or your user's system?

I would probably read that caution as "don't rely solely on CAS".

You can provide a handler for the AppDomain resolve assembly name / type, and prevent particular types/assemblies from being accessed in your AppDomain. This might also help you prevent reflection from bypassing a whitelisting implementation (e.g. restrict access to the reflection types).

Btw, reflection can let you mess with non-public members as well, so don't ignore that.

Maybe all this combined with a "peer review/approved" approach to marking safe maps/plugins would be enough - then the user can be warned about the dangers of using a particular extension.

Add-ins might also be of interest: https://msdn.microsoft.com/en-us/library/bb384200.aspx and https://msdn.microsoft.com/en-us/library/bb355219.aspx

Justin Stenning | Blog | Book - Direct3D Rendering Cookbook (using C# and SharpDX)

Projects: Direct3D Hook, EasyHook, Shared Memory (IPC), SharpDisasm (x86/64 disassembler in C#)

@spazzarama

 
Advertisement

Roslyn cannot make the distinction between good and malicious intents. Something like encrypting all files in "my documents" is just business as usual for the system, but the majority of users certainly don't want a game to do that.

The overarching problem is that it is impossible to recognise harmful code in advance. And when all of your users get hacked by a malicious content pack that slipped past your inspection, it largely becomes your problem.

Yes, that's right. I'm just using it to figure out what can potentially do that encryption (or whatever) - or rather, only enable stuff that I'm pretty sure cannot.

Could you please elaborate on what you are trying to protect, your application, or your user's system?

I would probably read that caution as "don't rely solely on CAS".

You can provide a handler for the AppDomain resolve assembly name / type, and prevent particular types/assemblies from being accessed in your AppDomain. This might also help you prevent reflection from bypassing a whitelisting implementation (e.g. restrict access to the reflection types).

Btw, reflection can let you mess with non-public members as well, so don't ignore that.

Maybe all this combined with a "peer review/approved" approach to marking safe maps/plugins would be enough - then the user can be warned about the dangers of using a particular extension.

Add-ins might also be of interest: https://msdn.microsoft.com/en-us/library/bb384200.aspx and https://msdn.microsoft.com/en-us/library/bb355219.aspx

I'm trying to protect the user's systems. They'll download mods in the form of code, compile it and run it locally. There won't be a central server that keeps the mods, at least not at first, so any security measures have to be done on the users' local machines.

As you say, CAS (or whatever the new security model is called) is still useful. I'll probably leave it in place as an added precaution for PC builds. However, I don't want to be limited to only PC releases, so I need an alternative as well.

You're completely right about runtime checking via assembly resolves, I have that check in place already. As far as I know, those are the only assemblies you'll be able to touch, in addition to the ones given to the compiler.

Reflection is tricky, agreed. Private member access may be hard to stop, so I'll have to think about that closely. I can probably make tools that let you do "safe" reflection, or just disallow it entirely.

Peer-reviewing is definitely a safeguard too. If a mod messes with your computer, you will probably report it, or at least not recommend it to others. But this is obviously only a last resort.

How much of the language have you white listed, what library code do you allow to be referenced and what do the APIs in your system that you have exposed allow manipulation of?

I believe unless you really clamp what is allowed there will be more holes than a teabag. The more you clamp the less useful your scripting will be and so the less people will want to use it.

I am with Alberth. The code is either un-trusted or trusted and if un-trusted there is no real way to run it in a safe way if a determined person wants to break out of "safe" playground. Some people will think that is a game in itself :)

If there is anything you have allowed that provides a whiff of system level access all bets are off.

You will need to block expression trees. Give any access into this and you have huge troubles. Not sure how much of Linq that means you will need to block as that is the fundamental building block Linq is built on!!!

Also you will need to block CodeDom, Reflection.Emit and also any other technique/library that allows run time code generation as all of these will get around your protection by allowing code generation after you have "checked" the code deemed it safe and then compiled it to run

This topic is closed to new replies.

Advertisement