Can you pass a variable into the C# compiler code?
Asked Answered
H

2

15

Here's my current situation - I have an application that compiles C# code taken in as a string, using CodeDom. I have a SecureString that stores a password and I was wondering if there would be any way to pass that SecureString variable into the compiled code as a SecureString?

Here is some example code:

SecureString securePassword = getSecurePass();

string codeString =
        @"using System;
        using System.Security;

        namespace SomeProgram
        {
            class MyClass
            {
                static void Main(string[] args)
                {
                    SecureString securePass = new SecureString();
                    // somehow set this equal to the securePassword variable
                }
            }
        }";


// Compiler Code
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
string outFile = "output.exe"; 

System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = outFile;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, codeString);

I can't find a way to do this and I imagine that this isn't actually possible and instead I should possibly just store the password in an encrypted file and read it from that?

Halflife answered 28/7, 2015 at 16:26 Comment(4)
You're writing out an exe, so you anyway want to embed the password in it in a serialized form. It's not like you're providing a value to a running program.Bistro
(Which might be conveniently done by adding a resource to your assembly that contains an encrypted blob).Bistro
@Bistro That is a genius idea, are resources built into the actual EXE or would they be stored separately (in a separate file), because if they're stored separately then I might as well encrypt the string and output it to a txt file?Halflife
Yes they do, because they are EmbeddedResources. There are also LinkedResources.Bistro
I
4

I think you're confused about the concepts. You're trying to compile the password into an exe file, and you think that SecureString will keep your password secure. That's not what the SecureString is for. Read the documentation:

(SecureString) Represents text that should be kept confidential, such as by deleting it from computer memory when no longer needed.

SecureString will only protect your in-memory password by 1) encrypting it while it is in the memory so no other apps can sniff it, and 2) removing it from the memory once you're done with it.

If you compile your password into an exe, a hacker can easily get it from there even if it is encrypted. In fact, getting it from the exe is much easier than getting it from the memory. Encrypting it will only make it a bit harder, but a skilled hacker can still decrypt it after finding the key. The suggestion given by Gseg to compile it as an embedded resource and your suggestion of encrypting it in a text file, both will have the same issue.

It all comes down to the encryption key, where is it stored? If you store it in the exe file (because you need your app to be able to decrypt it), then the hacker will be able to find the key and use it to decrypt your password. You will need to store it outside the exe in a way that is not reachable by the hacker. So the real issue that you need to think about is: Where to store the encryption key so the app can read it, but the hacker cannot?.

Now, when your app retrieves the key, then now you can decrypt the password to a SecureString variable to protect it while it is in memory and remove it afterwards.

Isolecithal answered 8/9, 2015 at 21:43 Comment(0)
L
1

Well all you need is to figure a way to change SecureString to System.String.

Already answered here : How to convert SecureString to System.String?

string codeString =
    String.Format(@"using System;
    using System.Security;

    namespace SomeProgram
    {
        class MyClass
        {
            static void Main(string[] args)
            {
                SecureString securePass = new SecureString();
                {0} // use it the way u like
            }
        }
    }", SecureStringToString(securePassword));
Lexicographer answered 28/7, 2015 at 16:34 Comment(3)
I believe the OP wanted to keep the string secure in the process.Bistro
I already have a method that can do that but isn't hardcoding a password a very bad idea? (and yes, like GSerg said, keeping the password in a SecureString would be ideal)Halflife
@PhilJones- it's not possible, you need something that is secure in memory and then it is needed in raw format to be secure again.Lexicographer

© 2022 - 2024 — McMap. All rights reserved.