Destroy a string

  • Thread starter Thread starter Mark C
  • Start date Start date
Well, as long as it isn't interned, it should (AFAIK) simply get
collected when available... do you have a specific situation in mind?

Marc
 
Strings are objects and so, the GC controls when objects are removed from
the heap.
 
Not really, I assume you're worried about things like passwords ending
up in the page file and the like. MS introduced the SecureString in V2,
then revoked it in V3 (at least stopped using it) as it's just not
secure. You can also try playing with volatile char arrays, I've heard
that's an option in that you can be (fairly) sure it's overwritten when
you overwrite each element. I recall issues with volatile, but I don't
use it so don't know what they are. There are also some Win32 API calls
which can allocate a bit of the page file (working from memory here,
basically just google password dotnet secure, that sort of thing) but
again that's problematic.
Sorry for being nebulous, I did look at this a while ago and came to
the conclusion that no there's no bulletproof way of protecting
strings, just try and hold them in memory for the shortest period
possible.
 
I know a string is immutable, but is there any trick or any other way
to destroy a string

Thanks
www.quiznetonline.com
Not so much destroy the string as overwrite it:

/// <summary>
/// Overwrites a string in-situ. Useful for removing
/// evidence of keys, passwords etc.
/// </summary>
/// <param name="text">The string to overwrite.</param>
public static unsafe void OverwriteString(string text) {
const char overwriteChar = 'X';
fixed (char* cp = text) {
for (int i = 0; i < text.Length; ++i) {
cp = overwriteChar;
} // end for
} // end fixed
} // end OverwriteString()

The string is still on the heap, but the sensitive information it
contained is no longer there.

rossum
 
rossum said:
I know a string is immutable, but is there any trick or any other way
to destroy a string

Thanks
www.quiznetonline.com
Not so much destroy the string as overwrite it:

/// <summary>
/// Overwrites a string in-situ. Useful for removing
/// evidence of keys, passwords etc.
/// </summary>
/// <param name="text">The string to overwrite.</param>
public static unsafe void OverwriteString(string text) {
const char overwriteChar = 'X';
fixed (char* cp = text) {
for (int i = 0; i < text.Length; ++i) {
cp = overwriteChar;
} // end for
} // end fixed
} // end OverwriteString()

The string is still on the heap, but the sensitive information it
contained is no longer there.


The current location of the buffer is wiped, but if the string survived a
generation, the garbage collector has made copies :(
 
rossum said:
I know a string is immutable, but is there any trick or any other way
to destroy a string

Thanks
www.quiznetonline.com
Not so much destroy the string as overwrite it:

/// <summary>
/// Overwrites a string in-situ. Useful for removing
/// evidence of keys, passwords etc.
/// </summary>
/// <param name="text">The string to overwrite.</param>
public static unsafe void OverwriteString(string text) {
const char overwriteChar = 'X';
fixed (char* cp = text) {
for (int i = 0; i < text.Length; ++i) {
cp = overwriteChar;
} // end for
} // end fixed
} // end OverwriteString()

The string is still on the heap, but the sensitive information it
contained is no longer there.


The current location of the buffer is wiped, but if the string survived a
generation, the garbage collector has made copies :(

There may also be a copy on disk in swapspace, on automatic backups
and written on a post-it under the keyboard. It is not possible to be
completely secure, all that is possible is to make the attacker's job
more difficult.

rossum
 
rossum said:
rossum said:
On 3 Jan 2007 06:11:00 -0800, "Mark C" <[email protected]>
wrote:

I know a string is immutable, but is there any trick or any other way
to destroy a string

Thanks
www.quiznetonline.com
Not so much destroy the string as overwrite it:

/// <summary>
/// Overwrites a string in-situ. Useful for removing
/// evidence of keys, passwords etc.
/// </summary>
/// <param name="text">The string to overwrite.</param>
public static unsafe void OverwriteString(string text) {
const char overwriteChar = 'X';
fixed (char* cp = text) {
for (int i = 0; i < text.Length; ++i) {
cp = overwriteChar;
} // end for
} // end fixed
} // end OverwriteString()

The string is still on the heap, but the sensitive information it
contained is no longer there.


The current location of the buffer is wiped, but if the string survived a
generation, the garbage collector has made copies :(

There may also be a copy on disk in swapspace, on automatic backups
and written on a post-it under the keyboard. It is not possible to be
completely secure, all that is possible is to make the attacker's job
more difficult.

rossum


That's why the SecureString was invented, it get's allocated in a non swappable fixed
portion of the process heap, it's contents get's encrypted and it' doesn't need the GC to
get wiped-out.

Willy.
 
rossum said:
On 3 Jan 2007 06:11:00 -0800, "Mark C" <[email protected]>
wrote:

I know a string is immutable, but is there any trick or any other way
to destroy a string

Thanks
www.quiznetonline.com
Not so much destroy the string as overwrite it:

/// <summary>
/// Overwrites a string in-situ. Useful for removing
/// evidence of keys, passwords etc.
/// </summary>
/// <param name="text">The string to overwrite.</param>
public static unsafe void OverwriteString(string text) {
const char overwriteChar = 'X';
fixed (char* cp = text) {
for (int i = 0; i < text.Length; ++i) {
cp = overwriteChar;
} // end for
} // end fixed
} // end OverwriteString()

The string is still on the heap, but the sensitive information it
contained is no longer there.

The current location of the buffer is wiped, but if the string survived a
generation, the garbage collector has made copies :(

There may also be a copy on disk in swapspace, on automatic backups
and written on a post-it under the keyboard. It is not possible to be
completely secure, all that is possible is to make the attacker's job
more difficult.

rossum


That's why the SecureString was invented, it get's allocated in a non swappable fixed
portion of the process heap, it's contents get's encrypted and it' doesn't need the GC to
get wiped-out.

Willy.


The problems I have with SecureString are firstly that I cannot use it
directly, very few .NET methods accept SecureString as a parameter. I
have to take my sensitive data out of the secure string and transfer
it to something insecure, such as a string or a byte array, before I
can do anything useful with it. For example, none of the various
GetBytes() methods takes a SecureString as a parameter, I have to
write my own function to do this. I don't want to have to rewrite all
the .NET methods that can take a string as a parameter just so I can
have a SecureString as a parameter.

Secondly, I understand that SecureString is either uncertain, or not
present, in .NET 3, so I am reluctant to use something that I am just
going to have to rewrite when I come to upgrade.

SecureString is fine for storing something during the life of a
program, but it is not practical for anything other than pure storage.
In order to use it I have to put the secure data into other
non-encrypted containers. Hence the need to wipe those containers
when I am finished with them. I can wipe a byte array easily enough.
With a string I need to drop into unsafe code to do the wiping.

rossum
 
rossum wrote:

Secondly, I understand that SecureString is either uncertain, or not
present, in .NET 3, so I am reluctant to use something that I am just
going to have to rewrite when I come to upgrade.

Everything in .NET 2.0 is in .NET 3.0 as .NET 3.0 is just the addition
of a bunch of new libraries, effectively. (WPF etc.)

Jon
 
Ben said:
The current location of the buffer is wiped, but if the string survived a
generation, the garbage collector has made copies :(

Ben

The example could be modified to pin the string immediately after
creation, but before it is filled with the sensitive text. After
wiping the buffer you would unpin it. Pinning should prevent the GC
from making copies...I think.

Brian
 
rossum said:
rossum said:
On 3 Jan 2007 06:11:00 -0800, "Mark C" <[email protected]>
wrote:

I know a string is immutable, but is there any trick or any other way
to destroy a string

Thanks
www.quiznetonline.com
Not so much destroy the string as overwrite it:

/// <summary>
/// Overwrites a string in-situ. Useful for removing
/// evidence of keys, passwords etc.
/// </summary>
/// <param name="text">The string to overwrite.</param>
public static unsafe void OverwriteString(string text) {
const char overwriteChar = 'X';
fixed (char* cp = text) {
for (int i = 0; i < text.Length; ++i) {
cp = overwriteChar;
} // end for
} // end fixed
} // end OverwriteString()

The string is still on the heap, but the sensitive information it
contained is no longer there.

The current location of the buffer is wiped, but if the string survived a
generation, the garbage collector has made copies :(

There may also be a copy on disk in swapspace, on automatic backups
and written on a post-it under the keyboard. It is not possible to be
completely secure, all that is possible is to make the attacker's job
more difficult.

rossum


That's why the SecureString was invented, it get's allocated in a non swappable fixed
portion of the process heap, it's contents get's encrypted and it' doesn't need the GC to
get wiped-out.

Willy.


The problems I have with SecureString are firstly that I cannot use it
directly, very few .NET methods accept SecureString as a parameter. I
have to take my sensitive data out of the secure string and transfer
it to something insecure, such as a string or a byte array, before I
can do anything useful with it. For example, none of the various
GetBytes() methods takes a SecureString as a parameter, I have to
write my own function to do this. I don't want to have to rewrite all
the .NET methods that can take a string as a parameter just so I can
have a SecureString as a parameter.


I know, I know SecureString is not a silver bullet, but when used carefully it can raise the
bar, especially when passing strings to unmanaged code, the Marshal.SecureStringToXXX
methods are decrypting the string in unmanaged memory (process heap), and return a pointer
to managed code (an IntPtr. This pointer can be passed to unmanaged code, where i can safely
be used, not that this makes it that more safe, all you have is more control over the
lifecycle of the "single" decrypted copy. Question is, should we write more unmanaged code?

Secondly, I understand that SecureString is either uncertain, or not
present, in .NET 3, so I am reluctant to use something that I am just
going to have to rewrite when I come to upgrade.

See Jon's answer...


Willy.
 
rossum wrote:



Everything in .NET 2.0 is in .NET 3.0 as .NET 3.0 is just the addition
of a bunch of new libraries, effectively. (WPF etc.)
Thanks for the info. Scratch my second reason.

rossum
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top