How should I handle secret values in a project in source control? - c#

My question is essentially the same as this one but for a Windows Store App, c# and Visual Studio. I want to have an easy way to keep secret values in the project, in a file that can be ignored in (not checked in to) source control. How should I structure my project to store the app secret in a way that makes building/source control easy?
My first idea was to store it in an XML file (not checked in), and load it at runtime, but this leaves it available to the user who installs it, so it should be done at build time. How can I store a couple secret values and have visual studio replace them in my code when my project is built?

In my company we decide to you following solution. In config file we link sections with "secret" values in external configs.
External configs are on source control. First it wasn't but after a problem when our build server lost a disk we decide it it safer to store it on a place which has backup. The folder in source control (can be also on file server) is really restricted to read and write to only people who needs this. Build process checkouts "project" folder plus "configuration" folder and do build. After build "configuration" folder is deleted. Access to build server is also restricted.

One option is to store the secrets in source control, but store them in an encrypted form. In your development or build environments, use a environment variable to store the key, and decrypt on the fly. That way you get the benefits of source control while keeping your info safe.
It is possible to do this even if you are using app.config or web.config, you just need to modify the configuration from code at startup.
Erick

Updated
If you put a secret in an untrusted area (e.g. public source control), it is vulnerable. Even if it's encrypted, with enough diligence it can be retrieved.
The only way to really keep it out of reach is to have an external service that interacts with the 3rd party API. That has its own trade-offs (e.g. user authentication as you mentioned in comments). Especially if your developers need to utilize the 3rd party API when testing, I see no other alternative that will limit the secret's exposure.

Create a new class file in your project that has slots for all of your secret values, and holds dummy/test values for all of them. Check that into source control with the rest of your project, so that anybody building it without access to the secrets will get some sort of test version.
Then, create a copy of that class file with the real secret values, and put it somewhere outside of source control. Write a batch script in the pre-build event that looks for this class file, and if found, replaces the dummy file that is included in the project with it.
This way, your project can still be in source control and anybody can check it out, build it, and run it in the test mode. Your secret file/values are stored on your build server only, so only when you build the project there will it have the real values.
Do remember to back up your secrets file somewhere. And also remember that .NET code can be decompiled easily, so your secrets may not be as secret as you hope them to be - any user with a .NET reflector can see all of the code in your release assembly, including your secret class.

Related

Add config directly into C# assembly

I need develop some application, that will be distributed to user as a single executable file. User should click to some button like "Download" and get exe file, then he executed it, and upload results back to my site. App should not contain any installer or something like this, just run once and get result.
My application have a main executable like "myapp.exe" and several data files, that depends on current user. Now i have to generate SFX zip archive, that contains myapp.exe, datafiles and current user config. When user click "download", i'm adding user data to archive and provide it to user.
Problem is that SFX archive is very boring and difficult to maintain thing. I can't change it's interface, i can use only one or two zip libraries, that can create SFX arxhives.
Is there any way to use another container or pack user data into resources of my utility "on the fly"?
I've been doing that for an application where i needed to identify which user it was without asking for any credentials. Basically, some kind of token was bundled within application before download and then sent to the server.
From what i've found, there are 2 methods :
Using WiX: build the XML, call candle + light, send to client
Making a single MSI and editing its database just before sending it to client
We chose MSI database editing for its simplicity of implementation, but i've seen WiX in production recently and the result is pretty neat.
You can use Mono Cecil to programmatically alter assemblies, including their resources. In your case, you could use it to modify your assembly pre-download to add/modify embedded resources that contain the data for the specific user.
byte[] userData = ...;
EmbeddedResource resource = new EmbeddedResource("UserData", ManifestResourceAttributes.Public, userData);
assembly.MainModule.Resources.Add(resource);
You can then read the added/modified resource(s) (at runtime, post-download) using Assembly.GetManifestResourceNames and Assembly.GetManifestResourceStream.

Add custom version information to C# application

Application is a C# .Net 3.5 WCF Service.
I'd like during the build process to dynamically add some build information to the final binary and assemblies that can then be read programatically and sent back to the WCF client when it sends a GetVersionInfo request to the web service.
.Net assembly versioning isn't enough. I want to include additional string data that contains the state of the system at the time the application was built.
I'm thinking that I'd do this by adding a post build event to call a script to update the app.config file with the data I want. Does this sound about right, or should I be considering some other approach?
Update
I'd additionally like this string to appear in the "Special Build Description" property of the final exe. I.e. I'd like to right click on the file and see this information in the version tab for the file.
Thanks in advance.
I suspect a pre-build event may be more appropriate than post-build... have you considered adding a buildinfo.xml file (or similar) to be built into the assembly as an embedded resource? You could then load it with Assembly.GetManifestResourceStream. That way you don't need to worry about fitting in with existing files or anything like that - just overwrite buildinfo.xml with a new file in the pre-build step.
You have to decide how important it is that the information you want to exchange is tied to the executable file itself.
Updating the config file during the built is a workable model, but it places the information in a location where it could be altered by anyone with access and a text editor.
Updating information after a build in a compiled assembly is certainly possible, but it's fragile and breaks down if you ever decide to sign the assemblies. It's also a lot of work, since there's no built it support for re-writing assembly files in this manner.
An alternative you should consider, is creating your own custom assembly-level metadata attributes and assigning them during the build process. You could even place them in a separate code file (or append them to AssemblyInfo.cs) as part of you build.
You could also consider creating an embedded resource (an XML file, for instance), and retrieving it from the assembly manifest at runtime.
Either of the above approaches would require you to use a pre-build custom step rather than a post-build step.
Personally, I find the metadata attributes a convenient approach if there isn't a lot of data. Otherwise, I would consider using an embedded resource file.

c# help needed for application update

Hello guys I think the question i asked in the previous post is unclear OK fine. i am explaining in brief.
for example.
I have a form where i have placed one textbox and command button.
I have fired a event when i click the button the text under the textbox change to "hello" ok fine.
what is my problem is..
the application is created and I published ok.
After some week I thought I want to update my application. where in the place of "hello" I want "hi". I know that we can compile the whole project and publish it.
but I don't want my whole application to be updated.
for example.
What antivirus company do they have a definition file where they only update the definition file not the whole application. after the update it applies to whole application.
I want my application also to do same process like antivirus company do.
You should read that "Hello" from a content file (XML). Then you can just push out the new file.
Use a configuration file. You can add an application.config (or if you're developing a web app, web.config) file to your primary project. Within this configuration file, you can define AppSettings (which are built-in, usually simple and atomic string or number fields that the application will need), ConnectionStrings (which specifically provide information applications will need to connect to a database), or custom configuration sections (used for more complex, related sets of data that are loaded into custom classes you define, such as a basic company profile). Within your code, you access AppSettings by using the static ConfigurationManager.Appsettings[] collection; you tell it the name of the setting you defined in the file, and it returns the value (or null, if it can't find the setting you defined).
Related, but different, is the use of Resource files. Resource files usually contain a dictionary of location-specific data used by the UI, such as text strings, icons and images. Actual resources can be compiled into one big file, or resource files can be a list of paths and filenames to the actual resources. You can use resource files to create different "skins" for your application to be used by different companies by referencing images to use for UI elements, or to translate labels and other text on your application's UI. Resource files are accessed through a ResourceManager; you tell it where the resource file is, and it will load the information into a similar "dictionary"; you then tell it the name of the resource and you get the resource back.
For your specific question, I'll answer the same thing as Henk. But, I think that your real question is "How I do create patch in .NET".
You can check this link:
How can I patch .NET assemblies?
You could design your application to use plugins. This way you only have to update a plugin and not the whole application.
if you want to create a patch for asp.net application , first of all , you have to deploy your project with Web Deployment Project.
then choose Create a separate assembly for each page and control output in output assemblies tab and re-build your solution .
the result of deployment is bunch of DLL which mapped to each page or control.
Now if you changed one page's data (in code behind) , you need to deploy your project again but in this case you can just upload the changed dll file.

single exe with changeable settings

I am trying to make a simple application which will be used to point a web browser control to some of our web applications at my work. I would like to have only one exe file but also have an admin window to change some of the settings and have them persist when the application is closed. Is that possible? I have looked at the application settings resources part but as I understand that makes a file that loads the settings.
I don't want to have to parse a file or have anything but ONE file so please don't suggest doing that if it is possible.
Just use application settings - that will create a single file, you won't have to do any parsing, it'll all be fine.
It'll be separate to the exe file, but unless you meant that "ONE file" to include the executable and rewrite that on the fly, it should fit your description easily.
For example, let's build a console app that just remembers how many times it's been launched:
Create a new console application project
Go to the properties page, and click into the Settings tab.
Click on the link to create a settings file
Type in the table to create a setting called "LaunchCount" of type int. Make it either user scope or application scope, depending on whether you want it to be persisted per user or system-wide.
Hit Ctrl-S to save.
In the Main method in Program.cs, write this code:
Settings settings = Settings.Default;
settings.LaunchCount++;
Console.WriteLine("Launch count: {0}", settings.LaunchCount);
settings.Save();
Add the appropriate using directive for Settings (put the cursor in Settings and hit Ctrl-.)
Run the app several times, and observe the number increasing.
You can't have persisted settings without having a separate file...safely. You must either have a separate file, which is the standard and suggested approach approach, like the one created with Application settings, or you must use something like the registry to save settings.
Keep in mind, though, that using the registry is highly discouraged due to security reasons. Plus most companies don't allow access to registries anyway which means that anyone without this access could not use the settings feature.
There are several ways to do this. You can use a command-line argument to do that. Launch the app from the shell and put in your command line argument and change how it launches.
A UNIX-y approach is to look at the name of the exe and change behavior based on that. If I recall correctly, rsh and rlogin are the same executable - they just look at argv[0] to decide how to run. In windows, this is straight forward - look at System.Environment.GetCommandLineArgs - if there is a non-empty string in the 0th element of that, it will be your executable name.
For persisting settings, see Jon Skeet's answer.
I have to say that this is generally a bad idea, but I've done this before a long time ago in VB6. I created a Resource within the exe and then (somehow) directly manipulated it.
The problem is, is that this is usually not possible within the .NET framework due to it being memory resident. These guys tryed it out in .net and they ended up creating an program in IL to do the heavy lifting... Modify Emdeded String in C# compiled exe
Go with a settings file as Jon suggested!

how to store settings for deployable c# application?

I want to store settings for my C# application, such that default setttings can be easily shipped with my binaries and the end-user can change them using a simple text editor(or in some other simple way).
I seem to face several alternatives : a .config file, .settings file or a .resx file. What are the pros and cons of these?
Edit1: End-users are computer professionals mainly, so editing these files should not be much of a problem.
Edit2: The settings are something like connection strings, and some other parameters (mostly one-time stuff). Building some kind of GUI/API for changing them is not really an option. Also my application will not edit any of these values, so persistence through code is not required.
Yes, Project + Properties, Settings tab was designed to do this. Add your settings here, change the Scope to Application. That generates a app.exe.config file in your build direcctory, deploy it along with your EXE. Use Properties.Settings.Default.SettingName in your code to obtain the setting value. Your user will normally need admin privileges to edit the .exe.config file on the target machine to change the setting value.
The small print: settings do not work well for DLL assemblies, you have to merge the .config files by hand. When using the debugger, settings are retrieved from the app.vshost.exe.config file.
The .settings file is a helper file used by the IDE, ignore it. .Resx files store resources, they get compiled and embedded in a binary form in an assembly. They are not editable by the user.
I think you can have two ways of doing this.
For regular users, you can make a custom GUI that will make it simple for them to use.
For advanced users, they can edit the configurations using a text editor if it's stored in a text file (ini file, config file, etc..) or you can make an API.
The .settings file is typically used for user-specific preferences and configuration information (whereas the .config file is used for global settings for the application or anything that modifies the .Net runtime. Simply putting parameters in a .config file can alter the behavior of your application even without you writing a single line of code for it).
Check out the Settings article on MSDN for more: http://msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx
Since the file will be modified by the users, I think using app.config is not a good idea. What if they break the file structure? Or set an invalid value? Probably your application will crash directly.
One of the solutions would be to use a custom XML file. You will then validate it when your application starts. XSD will probably be the more elegant way to do it, but you can also parse it directly and validate it in code. If the file is invalid, instead of crashing, you will try to solve the problem, and if impossible, display a pretty error to the user, explaining that there is an error in XML at line n, position n, which is [error description here].
If the end user is really going to be editing them, I'm not sure I would want them editing my app.config file.
You have another couple alternatives that you haven't included. You could use an old-school .INI file that is simpler for an end user to understand. You could also use the registry. I would recommend the INI file, unless your users are very savvy, in which case use the .config file.
The answer depends on the deployment method. For instance, if you are using ClickOnce and offer updates, you might encouter problems using Application Settings.
I believe the best way to go is to create a GUI, something that is most certainly suitable for novice users. Given that you already excluded that option, use John's suggestion (ini files).

Categories

Resources