-1

I think this should be a quick question, and I hope this is a good place to ask it.

Edit: Maybe this will make the discussion, suggestions, and answers a bit more pointed: Given that I have a situation where I have no option but to pass a plain text password to an input element on an html web page, what is the most secure way I can handle that password also given that I am using a wpf password box to retrieve it from the user, I am using .SecurePassword to retrieve the password from the password box, and using the function detailed below to pass that secure string to the input element and then immediately submitting the form to the server.

I have written a small WPF application that automates a process for our office. As part of that application, a user ID and password is passed to an outside vendor. This application remains open on the user's desktop so this process can be performed multiple times over the course of the day.

As I've written the application now, the password is entered by the user into a wpf password box once, and the password property is only accessed when the vendor site needs it. At no point to I pass the password to another property or text string variable.

My question has to do with the security of this approach. I'm not an IT security expert, and we don't honestly expect to have any issues with this due to the internal implementation of it, but I did want to see how the password box stores that password.

It is my understanding that in this scenario the only time the password lives in memory in plain text is at the moment it is passed from our application to the outside vendor's application, which is a risk that is more or less unavoidable. The outside vendor has not provided us with an API, so the best we can do is vendor site input element.value = passwordbox.password

Can someone highlight potential risks of this approach, maybe an alternative method if one exists, or arguments for it's security if those exist.

Again, this is a small app to be used internally by one department. We aren't anticipating issues, but we are expecting to field a few questions about it. I've reviewed the Microsoft documentation, but I wanted to see if perhaps someone with more experience might have something to add.

Thanks in advance for all your help!

EDIT: Still working on this but I've gotten some good feedback that I've taken into account. I've adapted the approach from the page that Mare Infinitus posted, http://blogs.msdn.com/b/fpintos/archive/2009/06/12/how-to-properly-convert-securestring-to-string.aspx

Here is what I have now:

The user enters their password into the WPF password box. I have the following function:

Private Function ConvertToUnsecureString(ByVal SecurePassword As SecureString) As String

    If SecurePassword Is Nothing Then Throw New ArgumentNullException("SecurePassword")

    Dim unmanagedString As IntPtr = IntPtr.Zero
    Try
        unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(SecurePassword)
        Return Marshal.PtrToStringUni(unmanagedString)
    Catch ex As Exception
    Finally
        Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString)
    End Try

End Function

Using that function I'm passing the password to the input element like this:

InputEl.value = ConvertToUnsecureString(Me.PasswordBox.SecurePassword)

At the moment, that seems to be as good as it gets, but I'm still interested in further strategies / ideas that might be more secure.

MattB
  • 2,203
  • 5
  • 26
  • 48
  • If you care about security, you ask for the password when you need the password. You use a [PasswordBox](http://msdn.microsoft.com/en-us/library/system.windows.controls.passwordbox(v=vs.110).aspx) and best practices for handling these passwords. If you don't, then you really don't care about security, and you should stop worrying about it or pretending it is secure. Oh, and most security issues are internal to organizations. –  May 20 '14 at 16:25
  • Does the app run inside your DMZ? – Gayot Fow May 20 '14 at 16:34
  • @Will That... is why I'm using the password box. I can certainly clear the password and prompt for it each time it is required, but based on my understanding that wouldn't be all that functionally different than the approach I'm already using. If you see some way this approach could be improved, I'd love to hear specific objections and recommendations. – MattB May 20 '14 at 16:43
  • @GayotFow I believe it would be running in the DMZ. The user credentials involved are used to access a website with an application created by an external vendor using SSL and are only valid for that site, but I can't guarantee users aren't reusing a user ID and password combination that is also used for more sensitive systems on our intranet. That part is out of my hands though, I just want to do my part when it comes to not creating new security holes. – MattB May 20 '14 at 16:47
  • Things become really complicated if you want to store that password. – Mare Infinitus May 20 '14 at 16:51
  • @MareInfinitus I don't really have to. It was my impression based on all that I've read that prompting the user for the password using the password box each time the external vendor's app is loaded would not be any less secure than the approach I'm taking currently. I suppose I'd like to know how leaving it in the password box and retrieving it when needed is less secure but only for the sake of my own edification, not because I'm trying to be argumentative about it. It would be more convenient for the users, but it's also a small sacrifice. – MattB May 20 '14 at 16:56
  • Perhaps the following link is helpful for you: http://blogs.msdn.com/b/fpintos/archive/2009/06/12/how-to-properly-convert-securestring-to-string.aspx – Mare Infinitus May 20 '14 at 16:58
  • @MareInfinitus and everyone really, based on some of the other apps I see internally, this approach is already much more secure in comparison. I'd prefer not to elaborate further on that though, nor do I want to use that fact as an excuse for being lax in my own approach. – MattB May 20 '14 at 16:58
  • @MareInfinitus Actually that is very helpful. I was just searching for something like that, thank you! It is my understanding that the password box control handles the password as a secure string. Am I still correct in that understanding? – MattB May 20 '14 at 17:00
  • Can you just use their domain credentials? – Gray May 20 '14 at 18:21
  • @Gray Unfortunately no, different domain, different user credentials. It's an app provided by an outside vendor. – MattB May 20 '14 at 19:35

2 Answers2

2

If you really have to pass the password over as plaintext, try to reveal it as short as possible.

The following link can help on that: Properly convert secure string to string

There is really more on the topic, the single most helpful link for me was:

How to use secure string

I believe this is the most on security you can do if you really need a plaintext password.

But also check the following links:

ProtectedData API, CryptprotectData

Codeproject article on encryption

Mare Infinitus
  • 8,024
  • 8
  • 64
  • 113
  • Of course, converting a `SecureString` to a `String` defeats the purpose of the `SecureString`.. – Ryan Emerle May 20 '14 at 20:42
  • @RyanEmerle Do you have another suggestion? My only option for passing the password to the vendor is using a plain text string, but how would you propose I minimize or remove exposure risk as I pass it to the HTML element? – MattB May 20 '14 at 21:04
  • In my opinion, the purpose of SecureString is not completely destroyed. There are definitly cases where you need the plain text. You just have to make sure that it is revealed for the shortest possible time. I had to do that once for a login where the API required plain text passwords over the ether, how could tbat be handled on client side? – Mare Infinitus May 20 '14 at 22:00
  • Once the `SecureString` is converted to a `string` that new string is stored in the heap until it's collected by the GC. So, if your goal is to prevent the string from being recovered from memory, or a memory dump, then you've defeated the purpose of using a `SecureString`. – Ryan Emerle May 21 '14 at 16:08
  • @MattB - what you're doing is inherently insecure. If you're concerned about security, then find a different way to integrate with the third party. Use a secure authentication protocol, or accept the fact that if someone was determined enough, they could recover the password. If you aren't careful, even if you do implement a "secure" solution, it's likely not a secure as you think and all you have is a false sense of security. – Ryan Emerle May 21 '14 at 16:12
  • @RyanEmerle My understanding of ZeroFreeGlobalAllocUnicode is that it zeros out that memory and removes it from the heap. I'd agree that it is exposed for a fraction of a second though. I'd love to find a better way to integrate with the third party, but they're outside of our control. Due to the nature of our business we MUST work with them and this is what they've provided for us, we have no other options. Still, I see no reason to throw all caution to the wind, I seek to make the best of a less than desireable situation, nothing more and nothing less. – MattB May 21 '14 at 17:26
  • @MattB No, `ZeroFreeGlobalAllocUnicode` clears the memory allocated for the _unmanaged_ string. Once it because a *managed* string, you are at the mercy of the GC. You can easily test this by creating a memory dump with a `SecureString` then one that has been copied into a managed string (even with `ZeroFreeGlobalAllocUnicode`). I commend you for trying to find a secure solution. I'd just caution you to be wary of a false sense of security. – Ryan Emerle May 21 '14 at 17:46
  • @RyanEmerle Will do, and thank you for the information. I will test it to be certain. I like to understand how the objects and methods I use are working inside and out, both for the sake of writing good code and so I can answer questions from interested parties competently and confidently. I agree it's not completely desirable or secure, and that there will always be a window of opportunity there, but I'm trying to minimize it as much as possible. As I said before, we MUST (like in a regulatory sense) work with this organization. I'm just trying to make the best of it. – MattB May 21 '14 at 19:00
  • @RyanEmerle If you have the time, check out the source that was referenced in the answer. It shows how to use the smallest time that could be used to reveal the password. If you are in the position to change the API, well, do that. If you are not, make the best out of it. In my case HP was not willing to change anything, despite I wanted to use a more secure way and described how that could be achieved. They made me use a insecure way, so I had to make it the least insecure as I could make. – Mare Infinitus May 21 '14 at 22:13
  • @MareInfinitus You need to understand the lifetime of the managed string resulting the conversion from a `SecureString`. The memory allocated for that *managed* string _isn't_ cleared when that method is finished executing. It will remain in the heap until the GC runs. Even then, the memory on the heap will [not be cleared](http://stackoverflow.com/a/23087417/62195). This is the false sense of security I was talking about. – Ryan Emerle May 22 '14 at 13:29
  • From the author of that blog: [in the comments](http://blogs.msdn.com/b/fpintos/archive/2009/06/12/how-to-properly-convert-securestring-to-string.aspx#10423699) – Ryan Emerle May 22 '14 at 13:33
  • As I wrote above: If you have any chance to go a secure way, do that. If not, what options do you have? Not doing anything? I miss the business value in that. – Mare Infinitus May 22 '14 at 14:08
  • @MattB Please have a look at the updated answer. Have added the single most helpful link (for me) on that topic. I clearly states the flawes and how they can be handled. – Mare Infinitus May 22 '14 at 14:26
0

Come on straight from the documentation

PasswordBox.Password Property

When you get the Password property value, you expose the password as plain text in memory. To avoid this potential security risk, use the SecurePassword property to get the password as a SecureString.

PasswordBox.SecurePassword Property

paparazzo
  • 44,497
  • 23
  • 105
  • 176
  • I'm doing this now, but to get the password into the vendor app I still have to pass it as plain text, so it gets converted using the methods described on this page: http://blogs.msdn.com/b/fpintos/archive/2009/06/12/how-to-properly-convert-securestring-to-string.aspx It seems like given the circumstances this is the best that can be done with the potential exception of prompting for a password each time the task that the application is designed for is executed. I might do that, I just haven't seen any explanation for why leaving it in the password box is bad though. – MattB May 20 '14 at 19:38
  • Really that is what you are doing now? "so the best we can do is vendor site input element.value = passwordbox.password" I don't read that as SecurePassword. – paparazzo May 20 '14 at 19:52
  • Sorry, I meant "now" as in now that I've taken into account Mare Infinitus' suggestions above. What I have now is a sub that converts secure strings to plain text at the time they are passed. I'll update the question above since I don't think this will be a "one right answer" kind of thing to provide a little more information about the approach I'm taking now. – MattB May 20 '14 at 21:01
  • So you are doing what I suggested but you are doing it based on post from someone else posted a day later? – paparazzo May 22 '14 at 23:22
  • It was this comment on the original question posted by Mare Infinitus: "Perhaps the following link is helpful for you: blogs.msdn.com/b/fpintos/archive/2009/06/12/… – Mare Infinitus 2 days ago" – MattB May 23 '14 at 15:11