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
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.
“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.
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
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?
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
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.