I am not sure if simply using password_in_string_form = nil
would be enough.
No, it would not be enough. The object might or might not be garbage collected immediately, and even if it was, that does not cause the contents to be erased from memory.
However, unless they have been frozen, Ruby strings are mutable. Thus, as long as you do not freeze the password string, you can replace its contents with zeroes, or random characters, or whatever before you let go of it. In particular, this should work, subject a few provisos, covered later:
(0 ... password_in_string_form.length).each do |i|
password_in_string_form[i] = ' '
end
But care needs to be exercised, for this approach, which may seem more idomatic, does not work:
# SURPRISE! This does not reliably remove the password from memory!
password_in_string_form.replace(' ' * password_in_string_form.length)
Rather than updating the target string's contents in-place, replace()
releases the contents to Ruby's internal allocator (which does not modify them), and chooses a strategy for the new contents based on details of the replacement.
The difference in effect between those two approaches should be a big warning flag for you, however. Ruby is a pretty high-level language. It gives you a lot of leverage, but at the cost of control over fine details, such as whether and how long data are retained in memory.
And that brings me to the provisos. Here are the main ones:
As you handle the password string, you must take care to avoid making copies of it or of any part of it, or else to capture all the copies and trash them, too. That will take some discipline and attention to detail, because it is very easy to make such copies.
Trashing the password string itself may not be enough to achieve your objective. You also need to trash any other copies of password in memory, such as from upstream of isolating the password string. If yours is a web application, for instance, that would include the contents of the HTTP request in which the password was delivered to your application, and probably more strings derived from it than just the isolated password string. Similar applies to other kinds of applications.
passwords may not be the only thing you need to protect. If an adversary is in a position where they can steal passwords from the host machine's memory, then they are also in position to steal the sensitive data that users access after logging in.
For these and other reasons, if the security requirements for your server dictate that in-memory copies of user passwords be destroyed as soon as they are no longer needed, then (pure) Ruby may not be an appropriate implementation language.
On the other hand, if an adversary obtains sufficient access to scrape passwords from memory / swap, then it's probably game over already. At minimum, they will have access to everything your application can access. That doesn't make the passwords altogether moot, but you should take it into consideration in your evaluation of how much effort to devote to this issue.