There are not that many applications today that don’t store some sort of settings either locally or to a remote location. User preferences, passwords, keys and whatnot often needs to be somehow stored for the application to later reference that data.
However, often developers do think about the best possible solutions to save some application data to make it less accessible outside the application, since not all the entire dataset processed by the application should be made public. This includes, but is not limited to passwords, license keys or the user’s personal data like credit card numbers or any other sensitive information.
One of the ways to store some information is by using the Settings functionality provided by the .NET Framework. For a .NET application, the developer can define two types of settings with different scopes – Application and User settings.
Settings that are defined with the Application scope are read-only and cannot be assigned at runtime. So the use of these settings is limited to application-based events and therefore is not really the case for data that depends on the user. For example, you could store here such data as a hash or checksum used to generate the license key or any other setting that you are sure you won’t need to change later on but at the same time you are sure that the application will use them.
The user-scoped settings have a different purpose, since these can be modified at run-time and therefore are perfect for dynamic settings. However, there is a thing that is often overlooked when using this type of settings – where and how these are stored.
The user-scoped settings are stored in a XML file on the local computer (in the AppData folder). This renders it to be one of the worst possible places to store passwords and sensitive information (and yes, there are people that do this in their projects).
The general format for user settings looks like this:
<?xml version="1.0" encoding="utf-8"?>
<setting name="Password" serializeAs="String">
Doesn't seem very secure to me. But then what could be the solution?
The solution is using the same user-scoped settings, but with some additional protection. For example, never store password strings or connection strings (or any other sensitive information for that matter) in their initial form in the user-scoped settings. Instead, hash the data with MD5 or SHA1 (.NET provides built-in functionality for this). In case you don’t want to solely rely on basic encryption, you can always add salt to make it less possible to break the hash.
Once hashed, the application takes the responsibility to hash the data that is passed to it and compare it to the one stored on the local machine. This way, even if someone finds the settings file, nothing could be done since no private information is exposed. It was shown that even hashes can be broken, however this is less likely compared to the probability of the file being found and the plain text read.
Another way to store some settings would be the system registry, but that requires elevated privileges, so that is not always a method to rely on (however, still a way to make settings accessible system-wide). Registry settings are useful when you know that these can be used by other applications, for example, by updater mechanisms or by application validity verifiers.
When storing application settings, consider some of these tips:
• Decide whether the information you want to store should be public or not
Probably it doesn’t make much sense to encrypt and protect user preferences, unless it is a high-security system. Therefore, you need to be sure to only protect sensitive information. This will save resources and time.
• Make sure you know the risks
When storing some sort of settings that expose user information, make sure that you know the risks that come with it, like the possibility of those to be read by the end-user or by an unauthorized user. Never assume that the user won’t know the location of the settings file. Choose the best way depending on where the application will be used.
• Take security measures
Hashing is just one of them. There are plenty more ways to secure the information, like storing data in a secure database. Make sure you know the client environment and possibilities before taking this decision.
• Never store sensitive data in plain text
That applies to secure databases and password-protected files. You never know how those can be broken or opened. Therefore, never assume that someone won’t be able to reach that key string you’ve stored somewhere. Encrypt it either by using a hash or by implementing your own encryption algorithm.
As a conclusion, secure settings storage is a key element in pretty much any application. Although seems to be that the advice here is quite obvious, there are developers that often do not consider these things when writing their projects. Therefore, this is one of the elements that should be carefully thought and designed to suit the user needs and assure the best possible security for the user's private information.