2

I'm about to create an authentication module in my C#/WPF application. To authenticate the user, I would like to use NetworkCredential to store the credentials.

Credential = new NetworkCredential(credential.UserName, credential.Password);

Where the credential.UserName is a string and credential.Password is of the type SecureString. When debugging the application I can see the password in plain text as well as in secure string

enter image description here

Why is the password exposed as plain text? Isn't this a possible security threat?

Thanks for answering.

EDIT:

For the record, the NetworkCredential object shall be used on the WCF client, like this:

client.ClientCredentials.Windows.ClientCredential = Credentials
Tobias Moe Thorstensen
  • 8,395
  • 12
  • 66
  • 132
  • 3
    Isn't which a possible security threat? That you can inspect it at run-time if you're debugging? You can do most things during run-time with a debugger attached. –  Sep 23 '15 at 12:48
  • 1
    @JayMee I think the point being that since `NetworkCredential` takes a `SecureString` in the constructor, it ought to not immediately then expose it as a plain text property on itself, and to anyone else that's looking. "Thanks for passing me this secure information. Hey everyone, look at this!" – James Thorpe Sep 23 '15 at 12:51
  • I'm not sure I understand. So what should we expect to see as the value of `SecureString`? An encrypted string? I'm not the best person to answer this (which is why I'm commenting instead), I'm genuinely curious what the threats may be. –  Sep 23 '15 at 12:54
  • 1
    @JayMee No I'm saying the `NetworkCredential` shouldn't take a `SecureString`, get it's value and expose it as a normal `String`. What's the point in passing it a `SecureString` if it's going to do that with it? Me too - I'm just (hopefully!) clarifying the question a bit... – James Thorpe Sep 23 '15 at 12:55
  • 1
    @JayMee The question is, why is there both a `SecureString SecurePassword` and `string Password`. `SecurePassword` doesn't seem very secure if you can get its actual value from `Password`. It is counter-intuitive. – sab669 Sep 23 '15 at 13:01
  • @sab669 Secure *how*? What kind of security did you lose by having an extra property that converts the secure string to a normal string? How is it different from doing the same thing with a method call? The contents of the secure string have *never* been hidden from *your* application. – Luaan Sep 23 '15 at 13:07
  • @sab669 Properties are not required to be backed exactly by fields. As the accepted answer shows, the password string is *not* stored in the object. – poke Sep 23 '15 at 13:15
  • @sab669 If that's how you deal with things, you have grave security issues indeed. The whole point of `SecureString` is to protect against *outside* threats, not *your own application*. What would be the point of that? No matter the security of `NetworkCredentials` or anything else, I could always simply snatch the password when the user enters it, no need to muck around hacking `SecureString`. – Luaan Sep 23 '15 at 13:15
  • Well I clearly have some sort of fundamental misunderstanding of what's going on here. Let's take a hypothetical situation where we pass this `NetworkCredential` object over a network. What is there to stop someone sitting there with a packet sniffer of some sort from looking at this object and viewing its public `Password` property? I suppose the argument then falls to "Why didn't you secure the connection?" but let's ignore that and assume you're under the assumption that you don't need it since `SecureString` sounds safe for transmission. – sab669 Sep 23 '15 at 13:20
  • 2
    @sab669, because the Password property is code and not data. A packet sniffer examines data, and does not execute code; indeed there is no Password property/code in the packet for the sniffer to execute, just data, and the Password property is not in the packet data. – Polyfun Sep 23 '15 at 13:25

2 Answers2

13

The NetworkCredential class internally always stores the password as a SecureString:

 public string Password {
        get {
            ExceptionHelper.UnmanagedPermission.Demand();
            return InternalGetPassword();
        }
        set {
            m_password = UnsafeNclNativeMethods.SecureStringHelper.CreateSecureString(value);
        }
    }

When someone needs to retrieve the password as plain text (which at some point will be needed, either from this class or somewhere further down the chain), it retrieves it from the secure string:

    internal string InternalGetPassword() {
        string decryptedString = UnsafeNclNativeMethods.SecureStringHelper.CreateString(m_password);
        return decryptedString;
    }

When using the debugger, it shows the properties, so the value is retrieved from the SecureString

James Thorpe
  • 28,613
  • 5
  • 64
  • 82
2

SecureString has nothing to do with encryption! (a gross oversimplification - it's possible it's also encrypted, but that's not all that important here; if you create a SecureString from a normal string, you've already negated plenty of gain of SecureString - short-term)

It's simply a string that can be deterministically deallocated. This is important for security reasons, since .NET strings may be very long lived (for interned strings, the whole life of the application).

NetworkCredential is not used for storing credentials - it's just a simple wagon to get them where they are going - a common API, basically.

Luaan
  • 57,516
  • 7
  • 84
  • 100
  • But why have a class that takes a `SecureString` as a constructor parameter ("Hey you can trust me with this") only if it then exposes it as a normal `String`? – James Thorpe Sep 23 '15 at 13:00
  • @JamesThorpe Why wouldn't it? You have the `SecureString` property to get the secure string. Most APIs don't give you any way to *use* a `SecureString`. It's an opt-in feature, really. The `string` is created on demand, when you query the `Password` *property*. – Luaan Sep 23 '15 at 13:01
  • I'm aware of the fact that `SecureString` has nothing to do with encryption, but why does the `NetworkCredential` expose my password as plain text? Wouldn't this store the password as plain text in memory? – Tobias Moe Thorstensen Sep 23 '15 at 13:02
  • Because as soon as you've passed your supposedly `SecureString` to this class, it's no longer given the same security? – James Thorpe Sep 23 '15 at 13:02
  • 2
    @JamesThorpe `Password` is a *property*. The string is only created if you *explicitly ask for it* - of course, the debugger tends to query all the properties of a watched object. The string doesn't exist in memory until you ask for that conversion. – Luaan Sep 23 '15 at 13:04
  • 2
    @TobiasMoeThorstensen It simply gives you a way to read the password as string. If you *don't* do that, and keep using the `SecureString` property, there's no "breach". The `Password` property is there simply for the APIs that don't support `SecureString`. – Luaan Sep 23 '15 at 13:06
  • @Luaan Yes - just realised that and went looking for the relevant code :) – James Thorpe Sep 23 '15 at 13:10