noelicus
noelicus

Reputation: 15055

Clearing a System.String in C#

Will this overwrite the contents of my string:

unsafe
{
    fixed (char* chars = str)
    {
        for (int i = 0; i < str.Length; i++)
            chars[i] = '1';
    }
}

The background is I'm using NetworkCredientials, in which you set the password using a plain old System.String. I'd like to "clear it" afterwards, if that's possible. Any suggestions on how to do this are welcome, but the main question is to understand if fixed will really give me access to the underlying char array. Thanks!

Edit

I would like to understand what is going on here - if a string object is immutable, and fixed doesn't let the object move then what's happening in the code posted? Where are those characters being written to?

Upvotes: 5

Views: 1212

Answers (3)

Wim Coenen
Wim Coenen

Reputation: 66753

I would like to understand what is going on here - if a string object is immutable, and fixed doesn't let the object move then what's happening in the code posted? Where are those characters being written to?

Strings are only immutable if you play by the rules. Here you are actually mutating the string by using unsafe code. (It's even possible with code that is "safe" in the sense that it passes peverify but that bends the rules in other ways, e.g. by calling the non-public AppendInPlace method via reflection or by abusing union structs.)

Breaking the rules like that is dangerous. It could interfer with string interning. It could corrupt memory locations which the .NET runtime relies on, like the TypeHandle and syncblk bytes that exist at the start of each .NET object. Etc.

Upvotes: 2

Cyril Gandon
Cyril Gandon

Reputation: 17058

System.String is immutable, so you can't modify it.

From MSDN:

Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this.

If you need to erase the string for security reason, try looking at SecureString.

In fact, your code mutate the string, you can see an answer From Eric Lippert here: String immutability in C#:

You can create a type where the CLR enforces immutability on it. You can then use "unsafe" to turn off the CLR enforcement mechanisms. That's why "unsafe" is called "unsafe" - because it turns off the safety system. In unsafe code every single byte of memory in the process can be writable if you try hard enough, including both the immutable bytes and the code in the CLR which enforces immutability.

If you are really restricted to a version of C# without SecureString, then you have to use unsafe code. But maybe the best solution is to try harder to change version.

Upvotes: 6

Jon Skeet
Jon Skeet

Reputation: 1501976

Use the NetworkCredentials constructor overload taking SecureString instead. The whole reason for that overload is to avoid this problem. You shouldn't go trying to mutate System.String instances. (It's certainly possible with reflection, but should be avoided.)

Upvotes: 13

Related Questions