CSharpCodeProvider - Is it abusable? - c#

Apologies for the shortness of the question, however I don't think it needs much elaboration.
Any there any security implications caused by using the CSharpCodeProvider and could it open a server up for attack?

It depends on how you use it. Here is a summary sorted from the safe use to a use that you certainly don't want to allow (when running the code on a server or some environment that you want to control):
If you use CSharpCodeProvider just for generating C# source code, then you only need a permission to save the generated files to some directory or to noting at all (if it is possible to get the code generated into a memory stream)
If you use it for compiling generated C# source, then you need a permission to run csc.exe (which may not be available in some limited environments such as shared hostings).
If you just generate files & compile them, then it probably won't be harmful (although someone could probably abuse your application to generate many, many files and attack the server using some kind of DOS attack.
If you also load & execute the generated code, then it depends on how you generate it. If you assume that there are no bugs in C#/CodeDOM and can guarantee that the generated code is safe, then you should be fine.
If your code contain things such as CodeSnippetExpression that can be provided by the user (in some way) than the user can write and run anything he or she wants on your server, so this would be potentially quite dangerous.

Sort of. On the surface it's not a direct risk, because you're not running code, just compiling it. However, there's nothing that says that the C# compiler doesn't contain some sort of bug that, given the right malicious input, would cause it to bail out and start executing commands directly.
However, if you later execute the compiled code (and presumably you do -- otherwise why would you compile it to begin with?), it will be running the same context as you are. Obviously, that has all kinds of unpleasant security implications, much like using the quasi-analogous eval() feature of other languages.

It depends on the source that you are compiling. If you have enough control over the source, then it might be an acceptable risk. If you are allowing someone outside of your sphere of trust supply code to the compiler, it might be an unacceptable risk.

Related

Is there absolutely no protection for Windows applications on dotnet?

I am in the middle of developing an application in Winforms and there just doesn't seem to be any protection from decompilation of the executables and other generated assemblies... there are tools that decompile literally within seconds. There are obfuscators available; however, I am specifically looking for a free one.
I store some pretty sensitive strings within the application, and though I try my best to keep them encrypted or in the local sqlite database, there is always that one, single point of failure that leaves the entire application vulnerable. I checked out a couple of obfuscators, both open source and commercial offerings. The open source one seems to be broken, and the commercial ones are priced quite steeply, which is unaffordable for an indie developer like me.
I am aware that an executable has to run in memory, and this in itself makes it vulnerable. And a determined attacker can eventually decompile an application. However, I want to make this process as expensive as possible. At the very least I would want to protect the strings within my application.
My question is, is there just no way to protect an application assembly from getting reverse engineered if I decide not to use any of the expensive options available?
There's lots of protection in Windows. But it's all there to protect the your users from you, not the other way around.
The simple fact of decompliation is: "As long as a computer can still execute it, it can also still decompile it."
Execution is a process that translates binary into actions.
Decompliation is a process that translates binary into code.
If one is blocked, the other is blocked as well.
Obfuscation can make it harder to read the decompiled code. But that is about all it can do.
I store some pretty sensitive strings within the application, and though I try my best to keep them encrypted or in the local sqlite database, there is always that one, single point of failure that leaves the entire application vulnerable
Every string, is only as save as the place you keep it at. The same applies for encryption keys. There are 2 limited workarounds:
if it is around comparing the input to something in the backend - like you do with passwords - password security can work. Modern PW security means not even the Adminsitrator can figure out the passwored, yet you can still compare user input to it.
You could move the strings into a seperate application. Instead of giving applications the SQL Server Connection string, you give it access to a WebService that you control. Only the WebService actually knows how to contact the Database.
It depends on your practical scenario what you can do. But in the end, if a string or other peice of information is to be useable, it is vulnerable in memory.

Is there something better than preprocessor directives (#if, etc) in C#?

Most questions of this type are seeking to alter the program behavior (things that could be decided at run time) or want to deal directly with debug printing. This is a bit different.
I have code that depends on a peripheral (like a card reader). Sometimes I don't use it, which means the library isn't present. (And I'm being nice, because "library" turns out to mean installing a 2GB software suite). When I remove the library, I can't open the device. If I can't open the device, I can't create the class member that uses it. With the class inoperative, I can't call its methods from within the code. Therefore, I can't just choose not to execute it; I need it to go away since it will not compile without the library.
Preprocessor directives like #if and all that are ok, maybe; but these things appear in more than one file, which means independently maintaining a #define at the top of each. I come from a simpler place (meaning, C) where one header file can be used to control this. I note that C# is rather hostile about #define (either the label exists, or not; no constants or calculations allowed), and that makes me think there's another way.
How do you handle this?
---Follow-up(s)---
I did read the "duplicate" Q/A's, and have a fairly good picture of what I'm dealing with. I didn't find those questions in my original search, but sometimes that's just how it is.
#Amy suggests that #define at the top is "not how it's done" but rather "put it on the command line". So, (if I realize we are sticking with this mechanism) the discussion might go to examining ways to have that happen . One does not simply drop to a terminal and do that. It happens as "IDE features" or "IDE hacks".
#Alexei Levenkov asks what I really want. I really want to (a) not get compile errors, and (b) do it by selectively leaving out the code. And, find the C# equivalent to the way I proposed.
Some more constraints are addressed by the fact that I haven't been using VS or C# for all that long. So I know a lot less than you all do. Considering I got the code from the last person and have to deal with what I see, I don't want to set up the person after me to have to figure out what "interesting" thing I might have done to make it work. Thus, things like hand-editing a project file may work but will also cause consternation down the line.
# Eric Lippert suggests "hostile" is really "sensible". I may have had my tongue too far into my cheek on that one. VS seems to be telling me I'm doing it wrong, so I sensed there's a "right way" I simply don't know about. As for the 2GB supporting application, I will go to various computers and pull down the repository and try out something, and so this "overhead" wants to propagate with it. It's worse if I'm linked through my phone to do the download. And if I build the application with everything included, the end user is then required to install that software suite before the program will run. In theory, they could be required to buy the software. If I sent you a tic-tac-toe game, and told you it wouldn't run until you installed Oracle, you'd probably pass on the whole thing.
I considered the "stub out the interface" idea, but there seemed to be more hooks into the class than I wanted to deal with. Plus, I don't know what these things do, so I have to know something about them in order to "fake" them.
In the end I decided that we're still largely using the #if scheme to get this done, and the replacement feature I imagined might exist, doesn't. And I'm using the provision in the project file(s) as cited by #Jim G. as it gets the job done and is only a little imperfect. It's good enough.
As #BJ Safdie said here:
Set them in your Compilation Properties or Build options.
You get to the build options by right-clicking the project and selecting
properties from the menu.

CA2122 DoNotIndirectlyExposeMethodsWithLinkDemands

I got error CA2122 DoNotIndirectlyExposeMethodsWithLinkDemands on this function :
internal static string GetProcessID()
{
return Process.GetCurrentProcess().Id.ToString(CultureInfo.CurrentCulture);
}
How to fix it?
I got error CA2122
It is not an error, just a warning. The code analysis tool you are using checks for lots of obscure corner-cases, the kind that the C# compiler does not complain about but might be a bad practice. And the kind that programmers are often unaware of. It was originally designed as an internal tool used by Microsoft programmers working on framework code. The rules they must follow are pretty draconian since they can't predict how their code is going to be used.
...WithLinkDemands
A link demand is Code Access Security (CAS) detail. It ensures that code has sufficient rights to execute. Link demands are very cheap, they are checked only once, happens when the code is just-in-time compiled. The "only-once" clause is what the warning is talking about, it is technically possible for code that has sufficient rights to execute first, thus allowing the method to be jitted, but used later by non-trusted code, thus bypassing the check. The tool just assumes that this might happen because the method is public, it doesn't know for a fact that this actually happens in your program.
return Process.GetCurrentProcess()...
It is the Process class that has the link demand. You can tell from the MSDN article which demands it makes. It verifies that the calling code runs in full trust, that it doesn't run in a restrictive unmanaged host like SQL Server and that a derived class meets these demands as well. The Process class is a bit risky, untrusted code could do naughty things by starting a process to bypass CAS checks or to learn too much about the process it runs in and tinker with its configuration.
How to fix it?
More than one possible approach. Roughly in order:
Always high odds that this warning just doesn't apply to your program. In other words, there is no risk of it ever executing code that you don't trust. Your program would have to support plug-ins, written by programmers you don't know about but still have access to the machine to tell your program to load their plug-in. Not very common. Proper approach then is to configure the tool to match your program's behavior, you'd disable the rule.
Evaluate the risk of untrusted code using this method. That ought to be a low one for this specific method, exposing the process ID does not give away any major secrets. It is just a number, it doesn't get to be a risky number until it is used by code that uses Process.GetProcessById(). So you'd consider to suppress the warning, apply the [SuppressMessage] attribute to the method. This is a common outcome, the framework source code has lots and lots of them.
Follow the tool's advice and apply the CAS attributes to this method as well. Simply a copy-paste from the link demands you saw in the MSDN article. This closes the "only-once" loophole, the untrusted code will now fail to jit and can't execute.

How to test whether a given functional code unit (C#) does NOT create/write any files to disk?

Imagine there's a mission-critical process that'll be used in a business which handles sensitive information (think of Credit Card, social security, patient records...etc). I would think this unit ideally should do whatever it has to do on-the-fly, meaning it won't intentionally write files to disk containing sensitive information. The idea here is that if the computer that runs this process is compromised, no sensitive information can be leaked, at least not by means of files.
What approaches could be taken to, say, come up with a unit test that will fail if the unit under test tries to write any file to disk?
There is the FileSystemWatcher (http://www.c-sharpcorner.com/uploadfile/puranindia/filesystemwatcher-in-C-Sharp/) however this requires you to know a specific directory. In your case this probably isn't very helpful since the program could write anything to disk any where. This introduces a unique problem. However, I have also found something called Detours from Microsoft. This appears to intercept all native win32 api calls. http://research.microsoft.com/en-us/projects/detours/ The issue with this is that its kind of hard to test, and integrating it into unit testing will be a challenge.
When you have to treat your software as "untrusted" in the sense that you need to prove it doesn't do something, testing becomes a complex task that requires you to run them on very controlled environments. When hooking in to the Win32 API, you will be deluged with API calls that need to be processed quickly. This can result in unintentional side effects because the application is not running in a truly native environment.
My suggestion to you (having worked several years doing software testing for Pharma automation to the exacting standards of the FDA) is to create a controlled environment, eg a virtual machine, that has a known starting state. This can be accomplished by never actually saving vmdk changes to disk. You have to take a snapshot of the file system. You can do this by writing a C# app to enumerate all files on the virtual drive, getting their size, some timestamps and maybe even a hash of the file. This can be time consuming so you may want (or be able) to skip the hashing. Create some sort of report, easiest would be by dropping them in a CSV or XML export. You then run your software under normal circumstances for a set period of time. Once this is complete, you run a file system analysis again and compare the results. There are some good apps out there for comparing file contents (like WinMerge). When taking these snap shots, the best way to do it would be to mount the vmdk as a drive in the host OS. This will bypass any file locks the guest OS might have.
This method is time intensive but quite thorough. If you don't need something of this depth, you can use something like Process Monitor and write the output to a file and run a report against that. However in my work I would have to prove that Process Monitor shows all IO before I could use it which can be just as hard as the method I spoke of above.
Just my 2 cents.
UPDATE:
I've been thinking about it, and you might be able to achieve fairly reliable results if you remove all references to System.IO from your code. Write a library to wrap around System.IO that either does not implement a write method, or only implements one that also writes to a log file. In this case, you simply have to validate that every time a write occurs using your library, it gets logged. Then validate using reflection that you don't reference System.IO outside of this new wrapper library. Your tests can then simply look at this log file to make sure only approved writes are occurring. You could make use of a SQL Database instead of a flat log file to help avoid cases of tampering or contaminated results. This should be much easier to validate than trying to script a virtual machine setup like I described above. This, of course, all requires you to access to the source code of the "untrusted" application, although since you are unit testing it, I assume you do.
1st option:
Maybe you could use Code Access Security, but the "Deny" is obsolete in .NET 4 (but should works in previous version):
[FileIOPermission(SecurityAction.Deny)]
public class MyClass
{
...
}
You may reactivate this behavior in .NET 4 using NetFx40_LegacySecurityPolicy
2nd option:
reducing the level of privilege may also works, as I know that downloaded app can't write on the disk and must use a special storage area.
3rd option:
Remove any reference to System.IO and replace by an interface that your code must use to write data to disk.
Then write an implementation that use System.IO (in a separate project)
In the nunit test, mock this interface and throw an exception when a method id called.
Problem is to ensure any developers will not call System.IO anymore. You can try to do this by enforcing coding rules using FxCop (or other similar tools)

Make an executable at runtime

Ok, so I was wondering how one would go about creating a program, that creates a second program(Like how most compression programs can create self extracting self excutables, but that's not what I need).
Say I have 2 programs. Each one containing a class. The one program I would use to modify and fill the class with data. The second file would be a program that also had the class, but empty, and it's only purpose is to access this data in a specific way. I don't know, I'm thinking if the specific class were serialized and then "injected" into the second file. But how would one be able to do that? I've found modifying files that were already compiled fascinating, though I've never been able to make changes that didn't cause errors.
That's just a thought. I don't know what the solution would be, that's just something that crossed my mind.
I'd prefer some information in say c or c++ that's cross-platform. The only other language I'd accept is c#.
also
I'm not looking for 3-rd party library's, or things such as Boost. If anything a shove in the right direction could be all I need.
++also
I don't want to be using a compiler.
Jalf actually read what I wrote
That's exactly what I would like to know how to do. I think that's fairly obvious by what I asked above. I said nothing about compiling the files, or scripting.
QUOTE "I've found modifying files that were already compiled fascinating"
Please read and understand the question first before posting.
thanks.
Building an executable from scratch is hard. First, you'd need to generate machine code for what the program would do, and then you need to encapsulate such code in an executable file. That's overkill unless you want to write a compiler for a language.
These utilities that generate a self-extracting executable don't really make the executable from scratch. They have the executable pre-generated, and the data file is just appended to the end of it. Since the Windows executable format allows you to put data at the end of the file, caring only for the "real executable" part (the exe header tells how big it is - the rest is ignored).
For instance, try to generate two self-extracting zip, and do a binary diff on them. You'll see their first X KBytes are exactly the same, what changes is the rest, which is not an executable at all, it's just data. When the file is executed, it looks what is found at the end of the file (the data) and unzips it.
Take a look at the wikipedia entry, go to the external links section to dig deeper:
http://en.wikipedia.org/wiki/Portable_Executable
I only mentioned Windows here but the same principles apply to Linux. But don't expect to have cross-platform results, you'll have to re-implement it to each platform. I couldn't imagine something that's more platform-dependent than the executable file. Even if you use C# you'll have to generate the native stub, which is different if you're running on Windows (under .net) or Linux (under Mono).
Invoke a compiler with data generated by your program (write temp files to disk if necessary) and or stored on disk?
Or is the question about the details of writing the local executable format?
Unfortunately with compiled languages such as C, C++, Java, or C#, you won't be able to just ``run'' new code at runtime, like you can do in interpreted languages like PHP, Perl, and ECMAscript. The code has to be compiled first, and for that you will need a compiler. There's no getting around this.
If you need to duplicate the save/restore functionality between two separate EXEs, then your best bet is to create a static library shared between the two programs, or a DLL shared between the two programs. That way, you write that code once and it's able to be used by as many programs as you want.
On the other hand, if you're really running into a scenario like this, my main question is, What are you trying to accomplish with this? Even in languages that support things like eval(), self modifying code is usually some of the nastiest and bug-riddled stuff you're going to find. It's worse even than a program written completely with GOTOs. There are uses for self modifying code like this, but 99% of the time it's the wrong approach to take.
Hope that helps :)
I had the same problem and I think that this solves all problems.
You can put there whatever code and if correct it will produce at runtime second executable.
--ADD--
So in short you have some code which you can hard-code and store in the code of your 1st exe file or let outside it. Then you run it and you compile the aforementioned code. If eveything is ok you will get a second executable runtime- compiled. All this without any external lib!!
Ok, so I was wondering how one would
go about creating a program, that
creates a second program
You can look at CodeDom. Here is a tutorial
Have you considered embedding a scripting language such as Lua or Python into your app? This will give you the ability to dynamically generate and execute code at runtime.
From wikipedia:
Dynamic programming language is a term used broadly in computer science to describe a class of high-level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, if at all. These behaviors could include extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system, all during program execution. These behaviors can be emulated in nearly any language of sufficient complexity, but dynamic languages provide direct tools to make use of them.
Depending on what you call a program, Self-modifying code may do the trick.
Basically, you write code somewhere in memory as if it were plain data, and you call it.
Usually it's a bad idea, but it's quite fun.

Categories