String sanitizing

I have implemented a sanitize! method into the String class to
properly erase Strings from memory (example usage: clearing a password
from memory), but I want to make sure that what I’m doing is actually
doing what I think it is.

Basically, is this code going to leave anything lying around in
memory because of any undocumented/strange behavior or side effects of
the []= method?

class String
def sanitize!
for i in 0…self.length
self[i] = 0
end
self.delete!("\000")
end
end

Also, feel free to recommend any “better” ways to do this.


Travis

“You get it, hm? But it’s not your head
that needs to understand!”
– Hatsumi O’Sensei

Hi –

On Sat, 6 Sep 2008, Travis W. wrote:

for i in 0…self.length
self[i] = 0
end
self.delete!(“\000”)
end
end

Also, feel free to recommend any “better” ways to do this.

Yes: don’t give it an unpaired !-terminated name :slight_smile:

http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist

I know that’s not an answer to your question, but I’m not sure about
the memory handling, especially as it might work in different Ruby
implementations and/or versions.

David

On Fri, Sep 5, 2008 at 10:13 PM, Travis W. [email protected]
wrote:

def sanitize!
Travis

“You get it, hm? But it’s not your head
that needs to understand!”
– Hatsumi O’Sensei

Maybe

42.times do
size.times do |i| self[i]=rand(256) end
end

This is a paranoiac approach and smaller values for 42 might do the
trick. Actually I have no idea if disk memory or RAM is easier to
reconstruct from magnetic residues.

Cheers
Robert


C’est véritablement utile puisque c’est joli.

Antoine de Saint Exupéry

2008/9/5 Travis W. [email protected]:

I have implemented a sanitize! method into the String class to properly
erase Strings from memory (example usage: clearing a password from memory),
but I want to make sure that what I’m doing is actually doing what I think
it is.

Copies won’t be affected. E.g. if you do

s1 = “…”
s2 = s1[1…-1]
s1.sanitize!

s2 will still hold most of the characters of s1. But there is no way
around this unless you want to resort to
ObjectSpace.each_object(String)…

end
end

Also, feel free to recommend any “better” ways to do this.

How about

class String
def sanitize!
gsub! /./, ’ ’
strip!
self
end

def sanitize_robert_paranoia!
gsub!(/./) { (32 + rand(96)).chr }
sub! /\A.+\z/, ‘’ # or slice! 0…-1
self
end
end

Kind regards

robert

Hi –

On Sat, 6 Sep 2008, Robert K. wrote:

s1.sanitize!

def sanitize!

self
end
end

But what would String#sanitize and String#sanitize_robert_paranoia do?
:slight_smile:

David

On Sep 6, 8:17 am, “Robert K.” [email protected] wrote:

s2 = s1[1…-1]
s1.sanitize!

s2 will still hold most of the characters of s1. But there is no way
around this unless you want to resort to
ObjectSpace.each_object(String)…

Ah, good point. Is there a way to identify where the String came
from? I.e. There’s no guarantee that the same password String isn’t
being used in a completely different context, so I don’t want to erase
a String that isn’t related to the String being sanitized.

end
self
end

def sanitize_robert_paranoia!
gsub!(/./) { (32 + rand(96)).chr }
sub! /\A.+\z/, ‘’ # or slice! 0…-1
self
end
end

Thanks for this suggestion; however, I think Murphy’s Law applies with
the additional complexity due to the use of regex. I’m afraid of
copies being accidentally made within the sanitize method itself.

And thanks, David, for message about the !. I’ve removed the ! from
the method’s name.


Travis W.

“Focus on the future for 50%,
on the present for 40%,
and on the past for 10%”
– Hatsumi Soke

But what would String#sanitize and String#sanitize_robert_paranoia do?
:slight_smile:

Assuming a conservative GC and Memory Management, also assuming that
no copies have been made of the string and furthermore assuming that
the string is not hold in any input buffers, it would avoid the memory
being scanned for an input password, but I believe you guessed
correctly, I did not really take this seriously ;).

Cheers
Robert

C’est véritablement utile puisque c’est joli.

Antoine de Saint Exupéry