Martin Bosslet <Martin.Bosslet / googlemail.com> wrote:
> 3. Are there better alternative ways how we could achieve this?

You can use IO#read / StringIO#read to overwrite an existing String:

----------- /tmp/pass.rb -----------------
pass = ""
$stdin.sysread(256, pass) # assuming a line-buffered terminal
io = StringIO.new("\0" * pass.bytesize)
io.read(pass.bytesize, pass)
p pass
Process.kill(:ABRT, $$)
sleep # wait for SIGABRT to hit us
------------------------------------------
$ ulimit -c unlimited
# using "hunter2" as my password:
$ ruby /tmp/pass.rb
hunter2
"\x00\x00\x00\x00\x00\x00\x00\x00"
Aborted (core dumped)
$ strings core | grep hunter
<nothing>

Unfortunately, using things like $stdin.gets to read passwords:

  pass = $stdin.gets

Instead of:

  $stdin.sysread(256, pass)

...Can leave a copy of the password in userspace IO buffers (stdio or
rb_io_t).  One has to avoid touching userspace IO buffering layers to
avoid leaving a trace of them in a core dump.