views:

467

answers:

5

How do you store a password entered by the user in memory and erase it securely after it is no longer need?

To elaborate, currently we have the following code:

username = raw_input('User name: ')
password = getpass.getpass()
mail = imaplib.IMAP4(MAIL_HOST)
mail.login(username, password)

After calling the login method, what do we need to do to fill the area of memory that contains password with garbled characters so that someone cannot recover the password by doing a core dump?

There is a similar question, however it is in Java and the solution uses character arrays: http://stackoverflow.com/questions/646224/how-does-one-store-password-hashes-securely-in-memory-when-creating-accounts

Can this be done in Python?

A: 

EDIT: removed the bad advice...

You can also use arrays like the java example if you like, but just overwriting it should be enough.

http://docs.python.org/library/array.html

Trey Stout
All password = "somethingelse" does is remove the reference to the old password one line earlier. It doesn't actually overwrite anything.
Miles
I see. Thanks for the info.
Trey Stout
A: 

Store the password in a list, and if you just set the list to null, the memory of the array stored in the list is automatically freed.

AlbertoPL
The level of indirection of storing the string in a list offers zero protection.
Miles
+11  A: 

Python doesn't have that low of a level of control over memory. Accept it, and move on. The best you can do is to del password after calling mail.login so that no references to the password string object remain. Any solution that purports to be able to do more than that is only giving you a false sense of security.

Python string objects are immutable; there's no direct way to change the contents of a string after it is created. Even if you were able to somehow overwrite the contents of the string referred to by password (which is technically possible with stupid ctypes tricks), there would still be other copies of the password that have been created in various string operations:

  • by the getpass module when it strips the trailing newline off of the inputted password
  • by the imaplib module when it quotes the password and then creates the complete IMAP command before passing it off to the socket

You would somehow have to get references to all of those strings and overwrite their memory as well.

Miles
Not to mention the possibility that the OS will swap your whole memory page out to disk, where it could sit for months.
jhs
+2  A: 

If you don't need the mail object to persist once you are done with it, I think your best bet is to perform the mailing work in a subprocess (see the subprocess module.) That way, when the subprocess dies, so goes your password.

zdan
A: 

There actually -is- a way to securely erase strings in Python; use the memset C function, as per http://stackoverflow.com/questions/982682/mark-data-as-sensitive-in-python/983525#983525

GothAlice