-3

I have a an application with a first screen for the login. The password is entered in a password textbox, which is a secure string.

My idea it is store this SecureString in a global application variable because I will need it in some actions, so I would like to avoid the user has to write the password each time. One action could be send an email, I need the user and the password, so I don't want the user write the password of the email acount each time he wants to send and email.

I have read some posts and I know that at the end I will need the plain text from the secureString and this is the weak point, so the beset solution it is to reduce the time that the plain text is in memory. Some solutions can be found here.

But my question is, how the global variable is a secureString, is it safe meanwhile it is not decode? If it is not a good option, there are another options that would be better but without the need the user type the password each time an action needs the password?

Thanks.

Álvaro García
  • 18,114
  • 30
  • 102
  • 193

2 Answers2

0

Centralizing data that is meant to be reused across an application is a standard design pattern. Let's say you have a group of web pages on top of which you wanna display the name of the user, or you need to cache the posts or profile of a particular user. Different frameworks provide different tools for this purpose, for instance in Vue.js, Vuex is offered to implement this mechanism.

In case of your question, you have not specified which framework you are using, whether it is ASP.Net, WPF, or even a pure C# application relying on OWIN. But yet no issues, there are a few ways that can allow you to achieve what you are after and you can chose whichever best suites your needs:

1- You can develop a cache layer in your app, and cache the password or other data through the lifecyle of a particular session. To do this, you can either rely on a "Concurrent Collection" or you can make use an EF Core In-Memory database. (IMemeoryCache is also available in ASP.Net Core)

2- In case the password is meant to undergo some interops, then I recommend you to go for a global cache server. To do so, you can use Redis or Alachisoft NCache.

3- In case that is a web application, then you can preserve the data in a cookie or the local storage of browser.

Keep in mind, the SecureString may not give you any security advantage as you expect with respect to the fact that as stated by Microsoft:

A SecureString object is similar to a String object in that it has a text value. However, the value of a SecureString object is pinned in memory, may use a protection mechanism, such as encryption, provided by the underlying operating system, can be modified until your application marks it as read-only, and can be deleted from computer memory either by your application calling the Dispose method or by the .NET Framework garbage collector.

That said; you have to look at the security aspect of this type from the perspective of memory and memory management. Finally, you have to implement your own security provider, such as hash generation or encryption in other achieve real security.

Transcendent
  • 5,598
  • 4
  • 24
  • 47
  • Well, in my case is a WPF application with the .NET version 4.7.2. This is a client that send queries to the sql server. There is no a layer in the server, like WCF, that validate the password, is the client who has to get the password to send the email, for example. – Álvaro García Jul 23 '18 at 18:44
  • @ÁlvaroGarcía: You can go for the the first option in my answer then, you can use a `ConcurrentDictionary` to preserve your passwords, and before preserving them you can hash them using the algorithm of your choice (I mean the one that is appropriate) – Transcendent Jul 23 '18 at 18:48
  • The concurrent dictionary, which would be the key and the value? If the concurrent dicrionary has the secureString, why to hash? Could yo detail the solution? Thanks. – Álvaro García Jul 23 '18 at 19:12
  • @ÁlvaroGarcía: The key would be the username or userId or any other identifier. You should not use a `SecureString` type in this case, on the other hand you have to hash the password. Hashing is considered a standard security mechanism in this case. – Transcendent Jul 24 '18 at 06:58
  • Then I have a concurrent dictionary with key the userID and as value the hashed password of the email account. But if it is the hashed password, I can´t use it to send an email, I have to get the password first. – Álvaro García Jul 24 '18 at 07:30
  • @ÁlvaroGarcía: Ok, based on your description, hashing won't be appropriate in this case. I recommend you AES as it is fast and efficient, but keep in mind, do you need encryption at all? Do you think that an attacker can dump your memory? and finally, have you considered any physical firewalls? – Transcendent Jul 24 '18 at 07:32
  • For store the credentials in database I was thinking on AES encription, but to get the data I will need the password in memory to decrypt it, so in practice, it is the same that get the password from the AES ecnryption and store in memory too, so I could save the cost to decrypt every time. Really I don't think the attacker couldn't dump the memory because is an internal application to work in LAN, but I would like to take this chance to learn about the best options in this cases. – Álvaro García Jul 24 '18 at 07:42
  • @ÁlvaroGarcía: SQL Database like SQL Server offer you encryption to a certain extent, you can research on that and use it if you find it appropriate. In case of a login function, hashing the password is the standard solution as long as you add `salt` to the hash to protect it against dictionary attack. In case of the email password, the only advantage encryption gives you is protecting the email account against compromise in case of information theft from the database. You can leave the pass un-encrypted in memory with no concerns. – Transcendent Jul 24 '18 at 07:48
  • 1
    Thanks for your help, I have a base to start. Thank you. – Álvaro García Jul 24 '18 at 07:52
  • @ÁlvaroGarcía: You are more than welcome. – Transcendent Jul 24 '18 at 07:53
-2

Storing a SecureString containing a password isn't safe. Although the string is encrypted, which should make it harder for snoopers to find out what it is, it's still there and could, potentially, be decrypted.

Actually, one of the main advantages of using a SecureString is being able to deallocate it once it's no longer needed.

Take a look here:

Overall, SecureString is more secure than String because it limits the exposure of sensitive string data. However, those strings may still be exposed to any process or operation that has access to raw memory, such as a malicious process running on the host computer, a process dump, or a user-viewable swap file. Instead of using SecureString to protect passwords, the recommended alternative is to use an opaque handle to credentials that are stored outside of the process.

Without deeper knowledge of you application, what I can tell you is this: if you must store a string containing a password, use a SecureString. But if you can, for instance, use Windows Integrated Security or any other mechanism for propagating credentials, even better.

Finally, no application is completely secure. You must understand your attack vectors... who is going to use the application, where it's deployed, etc. Otherwise you may be spending too much time worrying about a small thing (memory dump, for instance) and forgetting a much larger issue (is your database secure? are admin password safe?).

Bruno Brant
  • 8,226
  • 7
  • 45
  • 90
  • The main purpose to save the password is to be able to send email. The idea is the user log in the application, I get from database the credentials of its email account (username and password) that I would like to store in memory to avoid to have to enter the email password each time it wants to send an email. But if there are a better away to do that, I will thank another ooptions. – Álvaro García Jul 24 '18 at 06:56