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 Warlick wrote:

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

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

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

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

···

On Fri, Sep 5, 2008 at 10:13 PM, Travis Warlick <twarlick@gmail.com> wrote:

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

--
C'est véritablement utile puisque c'est joli.

Antoine de Saint Exupéry

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)...

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.

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

···

2008/9/5 Travis Warlick <twarlick@gmail.com>:

--
use.inject do |as, often| as.you_can - without end

Hi --

···

On Sat, 6 Sep 2008, Robert Klemme wrote:

2008/9/5 Travis Warlick <twarlick@gmail.com>:

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)...

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.

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

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

David

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

> 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)...

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.

> 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.

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

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.

···

On Sep 6, 8:17 am, "Robert Klemme" <shortcut...@googlemail.com> wrote:

2008/9/5 Travis Warlick <twarl...@gmail.com>:

--
     Travis Warlick

"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