Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 22 Jan 2012
Offline Last Active Today, 03:29 AM

#5255856 Using whitelisting to run untrusted C# code safely

Posted by Ollhax on 06 October 2015 - 12:06 PM

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.

#5255703 Using whitelisting to run untrusted C# code safely

Posted by Ollhax on 05 October 2015 - 12:49 PM

Thanks for the replies so far! I should have explained my situation a bit more. It's about the same as BitMaster's example of WC3 maps. I want to use C# for scripting-type of work. Even when limited, I expect it to be very useful. Some points for context:

  • Users will download mods as code and compile+run them locally. There's no downloading/running of arbitrary .exes or other files. I can examine the code thoroughly before running it.
  • I'll examine the actual semantic model of the code through Roslyn, not match raw code strings.
  • Disallowing the unsafe keyword should avoid problems with buffer overruns, etc. (Well, if I haven't missed something, which is why I'm posting this!)
  • Crashing isn't an issue. I can't help if a mod crashes the sandbox process, but it won't bring down the entire application at least. I imagine mods that crashes the game for you won't be that popular.
  • Allowing reflection isn't a requirement.

I'm interested to hear about specific ideas/examples for how you'd be able to attack this setup, given the constrains I mentioned above. I know it's a tricky thing to guarantee that something is secure, but at the same time I can't come up with a single concrete example in my setup where this would be an actual problem. If you'd like, consider it a challenge! smile.png


Side note: I use C# instead of Lua because I prefer that language, and I'm hoping to ride a bit on the XNA/Unity-wave. I can use Roslyn for real-time compiling, giving error messages, providing with intellisense-like tooling, etc. Also, it lets me use a common framework for my engine code and mod code. Basically, it saves me a *ton* of works, which makes this a feasible (more or less...) project for me.

#5255507 Using whitelisting to run untrusted C# code safely

Posted by Ollhax on 04 October 2015 - 08:36 AM

Hi there! I've been working on a proof-of-concept for a game-maker idea I've had for a while. It boils down to running user-written, untrusted C# code in a safe way. I've gone down the path of AppDomains and sandboxes, using Roslyn to build code on the fly and running the code in a separate process. I have a working implementation up and running, but I've hit some snags.

My biggest issue is that it seems like Microsoft have given up on sandboxing code. See https://msdn.microsoft.com/en-us/library/bb763046%28v=vs.110%29.aspx. They added the "Caution" box a few months back, including this gem: "We advise against loading and executing code of unknown origins without putting alternative security measures in place". To me, it feels like they've deprecated the whole thing.

There is also the issue that AppDomain sandboxing isn't very well supported across platforms. There's no support in Mono. I had hopes for a fix from the CoreCLR, but then I found this: https://github.com/dotnet/coreclr/issues/642 - so no luck there.

So! I've started exploring whitelisting as a security measure instead. I haven't  figured out how big a part of the .NET library I need to include yet, but it feels like I mainly need collections and some reflection stuff (probably limited to messing with public fields). I think I can do all this by examining the code with Roslyn and not allowing namespaces/classes that aren't explicitly listed.

I'm comparing my approach with Unity, which does more or less the same thing, e.g exposing only a safe subset of the framework. In their case it's an actual stripped down version of Mono (if I've understood it right), but seems to me the results would be pretty much the same if I get it right.



If you have experience with these kind of problems, would you say that is a safe approach? Am I missing something big and obvious here?

#5210790 Exclusive maximum in random functions

Posted by Ollhax on 15 February 2015 - 02:28 AM

Hi there! I'm working on some library functions and I've hit a problem. Why do people insist on having random functions (like Random(min, max)) where the max value is excluded?



  • It's counter-intuitive. Most rookies trip on this at least once.
  • It's less efficient in the approach I was going for.
  • It has weird states like Random(0, 1) being the same as Random(0, 0) (unless one should forbid the latter, which seems only worse). You also can't Randomize through the full positive int range [0-Int32.MaxValue] (which kinda isn't a problem, but still inelegant).


  • Bit simpler when you're randomizing an element out of an array (array[Random(array.Size)]). Basically fits in better in a world where 0 is the starting index.
  • Everyone does it this way, including the System.Random functions (working in C#).

I really don't like a randomization lib being modelled only for indexing arrays, but the fact that everyone does it this way is a much more convincing argument. Before I go make a decision and move on, is there something I'm not thinking about?