I am creating a desktop app that will sit on a PC and occasionally check a web server for updates to various settings.
The program will be using these settings frequently so I would like cache the settings in a file on the PC so it doesn't have to hit the server constantly. There are a lot of settings. I was thinking about storing them in an XML file but I need the file to be unreadable by the PC users.
How should I store the settings on the PC that the program can read and write to but the user cannot read?
EDIT: Sorry guys. The application is being written in C# using .NET 2.0. The application will only run on Windows. It is a console app that will run as a Windows Service.
Assuming that you are targeting the Windows platform, you can either
use the registry
use a configuration file
or use a database
Data can be encrypted in all 3 cases if needed. If you really have lots of settings, the registry is probably not the easiest way to do this. If you have a .net app, look at SQL Server Compact Edition, it is really light-weight, easy to deploy with your app, and does not need a runtime environment.
If the app is a service then it can run under an account that isn't the user's; then it's easy enough to keep the file hidden from him.
As a Windows app, you have your choice of the Registry or a file or a local database. For files, your choice of a simple properties file or an XML file.
For any of those, your choice of encrypted (just in case) or not.
If it is on the end users machine, sooner or later they can read it. If the program is running on their local machine, then they can make it do whatever they want. If this is some sort of a client-server program, you simply can never trust what the client says.
One of the easiest ways to store settings in .Net is to create a class that contains everything you want to keep track of, and then serialize it to and from the disk. Since this file just acts as a cache, you can probably just use a Binary Formatter, which will make the file only readable to those who know what they are doing.
Be sure to save the settings in a UAC friendly directory like ApplicationData.
you could write the aplication configs in a xml like this
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Test1" value="My value 1" />
<add key="Test2" value="Another value 2" />
</appSettings>
</configuration>
Regardless of if you store these settings locally, if you load them into memory a user can read them. If you transfer them across a network it is a pretty simple to scan network packets, even over an encrypted connection there are plenty of tools that will man-in-the-middle your own network connection for you (I've used OpenSTA for that, even though it isn't exactly made for it). Someone who really, really wants to see what you're using for settings will be able to see them if you're running something on their computer.
Now, having said that, keeping them in XML and just encrypting the file is probably the simplest solution. Even just compressing the file and changing the extension will keep away people who are merely curious about what settings you have.
Settings are pretty easy in C#.net. Creating a settings file can be done through the project's property pages (Settings tab). Then if you really want to, you could pick up the settings file and encrypt the root xml element either with symmetric or asymmetric keys
Then, as others have mentioned, keeping the keys and routines to edit the settings out of the user's hands is another problem. You could send the settings to the server on which the private key exists keeping only the public key on the client for decryption, have the server do the encryption/signing. Any tampering with the settings on the client you would know because the signature would fail. So, if you have the settings saved locally, the user couldn't read them without a bit of code and you can only decrypt them to use them; writing/creating would be done by the server.
Your idea for an xml configuration is a good start (the XML DOM is easy to navigated, well known, documented, etc.).
If you don't want the user to be able to read/edit the settings you could keep it in memory but you would lose the data from run to run. You didn't seem to indicate that the app would be restarted though so this may work for you. There is also the option of detecting when the app is shutting down and you can then dump you cache to disk.
You are concerned about users reading the file or modifying it?
Regardless - you can encrypt it with a random key and bury the key somewhere in the registry
Related
Database File and Application that reads the db. The application has a registration component added. If the user doesn't want to register they can simply download the open source application, copy the database to the new folder, run a batch file and the database opens in the application, completely eliminating the registration and whatever extra features were added.
I want to keep the database file inhouse, even if it means adding the db file into the resources of the main application. The file does require data to be written to that file.
I've gone as far as converting the batch file to an exe file and loading the database file or even renaming the database file to something obscure like abc.exe (Even though its a db file it can be renamed to anything)
Database file is renamed to an exe file for the time being, I would prefer to either have it encrypted somehow or somehow placed into the resources of my main application and accessed that way, I am just trying to limit the way the software can be pirated.
Encryption:
You can encrypt SQLite databases using extensions such as SQLite Encryption Extension. The usefulness of such encryption depends on what you are trying to do. If your application can read the keys to decrypt it, so can a hacker that can run your application. You can use Windows Data Protection API to manage the keys so that if someone copied the database from one windows machine to another, the database would be unreadable; but again, if the hacker can access the source machine, they can obtain the keys just like your application (but it would protect against a "dumb" user from just copying the files over).
Putting it in your "main application resources": If you mean embedding the database within the EXE, you are out of luck if you have a requirement to write the data. Generally speaking, an EXE cannot modify itself (though depending on OS/version/user permission/absense of antimalware agents, etc, you might theoretically accomplish a self-modifying EXE; but, if you want your app to work most of the time in the wild, this strategy won't succeed). Even if you did succeed in an EXE that read itself, loaded the embedded blob as a database, modified that database in memory, then rewrote the entire EXE with database exported as a new blob (of different size than the original, wreaking havoc on the assembly), it wouldn't help. The attacker can do what your app does and access the data. Do yourself a favor and follow the operating system's guidelines for writing user data. For Windows, this is generally reading and writing files to your Local App Data folder.
Renaming a SQLite database to have an EXE extension. What are you trying to accomplish? Obscurity? Renaming it to EXE might fool some users (certainly not the motivated user I've described above), but it also might accidentally fool anti-malware / anti-virus software running on your legitimate user's operating systems into thinking your application is writing malformed executables (which would be suspicious) and shut your application down, or at least prevent it from working correctly. This will cause your users to not use your application or a mountain of support for you. What does it gain? It stops a "dumb" user from trying to open it in a SQLite query tool?
All that said, if you want to limit your user's abilities to read the data stored on their own storage devices, you really can't stop a determined user. You can stop the less savvy users. The majority of users cannot run a reflector on a C# assembly and figure out what it is doing, but many can. If you want to stop the less savvy users, encryption of the data will stop most of them, and it will be the least likely approach you've discussed to prevent your application from working "in the wild".
I've built an installer that creates a website, application pool, and then assigns the website to the app pool. As part of this I allow the user to input different settings for various connection strings (allows the developer to set them to DEV / UAT etc.). I then modify the web.config with the settings input by the user.
As this is something that will only be installed by a small bunch of developers I'm not concerned with the security of the input (I'm aware they could put in anything), but more with whether it's considered bad practice to modify the web.config in this way?
I've read a few questions on here regarding how people do this and generally in each one there is someone saying that it's not a good idea to do this. The second answer on this question states that doing so will restart your application. I can see how this could cause problems if your user is in the middle of using the app, but for my scenario this isn't relevant. Is this the only reason to consider when doing this?
The warnings are usually applied when someone is talking about having an asp.net website update its own web.config file. But as I understand it, you're talking about updating it from your installer, and this happens before the site is used, so it should be fine.
And, of course, think about it the other way - what's your alternative to manipulating these files programmatically? Do you have any means at your disposal for manipulating these files that doesn't, at some point, have some program open the file and write to it?
Notepad? It's a program.
IIS Manager? It's a program.
Your installer? It's a program.
web.config is like the .htaccess file, in wordpress some plugins automatically updates these files accordingly.
This links might help you, I did have this same question the other day
Change a web.config programmatically with C# (.NET)
Just a (perhaps obvious) thought: Be careful not to overwrite any manual changes added after the installation.
If I had made some custom changes to a config file, I would not want them to be overwritten by a program. It does not sound as if this would happen in your scenario though, so if the solution works for you, I can't see any real problem.
I would like to create a c# application which will open when i open a folder automatically.
My c# application is intended to be like a password system, so that the contents in the folder can only viewed after logging in to my application. Everything is ready..........
but i am confused how to open my application directly while opening the folder with a c# script?
I have now created a application which will ask the user for name and password while opening the application and now i want to make it open through the folder to be locked , how to do it?
Ok, first of all if you want the folder to be secure you should encrypt it otherwise all the user has to do to gain access is kill the process.
What i would recommend you do instead is create a encrypted file. For example a zip file. Then all you have to do associate the file with the program and to unpack it with the password. Then when the user is done delete it and overwrite the temporary folder. It's really important that you overwrite it otherwise the encryption is useless.
If you want to avoid conflict with other programs that work with zip files you can make your own file type it does not affect the content of the file in any way.
I hope this helps.
To make sure I understand... you want to build an application that will, when someone tries to open it, will only open after they supply a password. Hmmm... okay. A specific folder, or any folder? Local folders or folders on network shares? I initially was thinking a file system watcher approach, but that will only work on change events, like copying, renaming, deleting, etc. So that won't work. The closest would be to check last accessed time, but that is an alert ex post facto, so this must be rejected. I'm not sure how you could do this in C#. What is wrong with the robust security options MS has already established, like global groups. That provides flexible restrictions on access. Especially over large amounts of folders. Are users going to have one password per folder? Too cumbersome. One password per user? Use Windows authentication to lock it down. How is this app storing the passwords?
I recommend trying to leverage existing technology to solve problems before trying to re-invent the wheel. You have omitted the scope of this, and what you have already attempted, so we may not understand completely.
Can anyone provide a best-practices example for where to store user preferences for a C# Windows app?
So far I've heard a number of options:
Some people are saying to store it in
SQLite. Is SQLite bundled with .NET
2.0 and immediately available for use to me?
Others have said to use the built-in
Application Settings... but I've
heard that the per-user settings here
disappear if you upgrade the app (an
obvious problem).
I've also considered just storing it
in a .xml file somewhere on disk...
but where it the "correct" place to
store that .xml file for the user?
SQLite is not included with .NET2, but you could ship it with your application
The built-in settings system works fine for simple apps - you do need to add a couple of lines of boilerplate to deal with version changes but it's not complicated.
You could put your xml file here:
Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData)
There is a lot of 'it depends' about your question, as you don't say how much of what types of data you need to store, nor if you have any other reasons to care where it goes.
The per-user settings "disappearing" can be solved thus: .NET ApplicationSettingsBase Should I call Upgrade() every time I load?
Storing user application settings in isolated storage seems to be a best practice.
http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage(v=vs.80).aspx
Storing settings as an xml file is perfectly fine.
Hey, I want to store application configuration data. Currently, I'm using INIs but they are too old and now I want to try something new. I'm on .NET platform using C#.
What solutions do I have? app.configs?
The scenario here is like that, I want to let other programs read the configuration data.
Yes, the various .config files (app.config, web.config, etc..) have replaced INI and, to a certain extent, the Registry as the preferred means of storing configuration data for your application.
Any program, .Net or otherwise, can read those files. .Net has the ConfigurationManager class and other languages can simply do XML parsing to get the values they need.
The standard approach with .NET is to use app.config files for application settings and user.config files for user specific settings (the location varies between XP and Vista though).
There's nothing to stop other programs reading the configuration data, you just need to have a configuration setting in the second (or third) application that tells it where to look.
The app.config would be the preferred way of doing things in .NET. Should work fine to read from other applications as well, as long as you give them the right path to the file. And it's just an XML file, so you can read it from non .NET apps as well.
If you're using Visual Studio, you can use Application Settings for this purpose. Just open the automatically added Settings.settings or create another one. They will be automatically available in Properties.Settings.Default and are stored as XML. You can also have multiple settings files for different purposes.
This is a Visual Studio concept rather than a .NET concept.
I often use an SQL table to hold my application settings. I create a singleton class, ususally called AppSettings, that I load with data from the table. The AppSettings class is then used to get the config values instead of directly accessing the config files. For ASP.Net apps, I instantiate the AppSettings class in the Application_Start event in Global.asax.cs.
Doing this gives me a way to allow the user to control some of the app settings, e.g. an email address for notifications. It also can simplify things when maintaining prod, QA, and dev versions of the app (assuming you have separate database instances for each)