2

Is it possible to use C# as a DSL in which the C# source code is edited by the end user in a TextBox, compiled while the application is running, then called by the already-running application?

I ask because in the next few months I will be needing to implement a simple math-crunching DSL (similar to somthing Rachel Lim blogged about at http://rachel53461.wordpress.com/2011/08/20/the-math-converter/ I am focused on the math-processing aspect of her code, not the XAML/Converter aspect). I would lean against just reusing her code because I want to add if-statements and possibly other features. If I can use C# itself, then I get all of the features without having to re-implement them.

If it is possible to do this, what framework or namespace or class would I want to use to accomplish such?

Please note that one thing I would do with the C#-derived DSL is hard-code all necessary using header statements, then remove all using statements entered by the savvy user. The purpose of this is to reduce the prospect of an end user trying to leverage my C#-like DSL into a full-fledged compiler against the wishes of their enterprise policy or without the knowledge of the site administrator. Is my proposed managing of using statements an adequate defense against user mischief?

Finally, if all of the answers up to this point are "yes", then what are the drawbacks of this approach, especially drawbacks of introducing a security vulnerability?

Paul

philologon
  • 2,093
  • 4
  • 19
  • 35
  • Why not use a scripting language for this? Python for instance already has .NET support. – System Down Oct 18 '12 at 22:35
  • 1
    http://stackoverflow.com/questions/3188882/compile-and-run-dynamic-code-without-generating-exe – Chris Oct 18 '12 at 22:36
  • @Chris Chris, it looks like your suggestion, http://stackoverflow.com/questions/3188882/compile-and-run-dynamic-code-without-generating-exe is the answer to my question (at least the first one). But I can't accept it (later tonight) unless you make it an answer. – philologon Oct 18 '12 at 22:38
  • If you're looking for basic math expression evaluation, you may be able to leverage existing libraries such as FLEE or NCalc: http://flee.codeplex.com/ or http://ncalc.codeplex.com/ EDIT: The benefit of these is you generally have much better control over security; you generally can't call arbitrary code unless you explicitly expose specific types to the consumers. – Chris Sinclair Oct 18 '12 at 22:38
  • 2
    The `using` directive is a compile-time concept. Extension methods aside, all it does is to create a convenient shorthand for types in the "used" namespaces. It's possible to write any C# program without a single using directive, so limiting their use would achieve nothing. +1, therefore, to erikkallen's answer – phoog Oct 18 '12 at 22:52
  • I see no point in doing something so complicated and error-prone instead of just implementing a simple compiler. – SK-logic Oct 19 '12 at 09:07

3 Answers3

4

Is my proposed managing of using statements an adequate defense against user mischief?

No. You'd have to remove references to fully-qualified classes as well. And then, the user can still use reflection to gain access to classes they have not referred to in either way.

You'll want to create a separate appdomain to contain the user's code, which you can then sandbox appropriately. Here is a relevant article on MSDN, which explains this process in depth.

porges
  • 30,133
  • 4
  • 83
  • 114
  • Thank you Porges. It looks like the link in your answer would be a key part of my research and implementation. – philologon Oct 18 '12 at 22:43
  • If the idea worked, it would be safe against reflection because he cannot add `using System.Reflection` (but the idea doesn't work). – erikkallen Oct 18 '12 at 22:44
  • @erikkallen: Good point. But yes, it's completely unsafe because if they really want to they can just create x86 machine code in memory. – porges Oct 18 '12 at 22:50
  • @Porges Porges, I would have accepted your answer too. So I asked four questions, got good answers to all of them, but can accept only one. Thank you very much. – philologon Oct 19 '12 at 01:01
1

Removing using directives will not help, unless you also find some way to prevent the user from writing e.g. System.Diagnostics.Process.Start("evilprogram.exe"). Doing this (without also preventing property accesses) will require you to use a C# parser.

You might, however, be able to use Code Access Security for this.

erikkallen
  • 33,800
  • 13
  • 85
  • 120
  • Can you give a little me detail on Code Access Security so I can find somewhere to read up on it? Or does the right link pop up just by googling that phrase? – philologon Oct 18 '12 at 22:48
1

Stackoverflow automatically converts link answers to comments now. How lovely.

Compile and run dynamic code, without generating EXE?

Anyway, the answer lies with Microsoft.CSharp.CSharpCodeProvider

Community
  • 1
  • 1
Chris
  • 27,596
  • 25
  • 124
  • 225