Today I will show you how to clear passwords in memory with Python, a feat that many people consider infeasible.
You might ask, “why would I ever need to do this?”
- Your password might be in the section of memory called the swapfile, which will survive a reboot. Attackers could open that file and see your passwords in plain view.
- Cold Boot Attack: Computers use memory that “only lasts until the power goes out” because its cheaper. However, it actually lasts longer than that, especially if frozen.
- A hacker might gain access to your program (ie. buffer overflow). S/he then scans your memory and finds the passwords.
This is easy in C, but in many languages like Python, strings are interned. The consequence of this is that when you use a string, it will probably remain in memory even if you “delete” it.
import sys import ctypes secret = "not so secret" location = id(secret) size = sys.getsizeof(secret) print hex(location), size # 0x1ae2ac0 37 # let's try deleting it del secret print ctypes.string_at(location, size) # H+Ơ not so secret # maybe we can overwrite it by making a new string? secret = "blah blah" print ctypes.string_at(location, size) # H+Ơ not so secret
As you see here. Even after the string has no more references (and supposed to be garbage collected), its still in memory.
The Solution
def zerome(string): # find the header size with a dummy string temp = "finding offset" header = ctypes.string_at(id(temp), sys.getsizeof(temp)).find(temp) location = id(string) + header size = sys.getsizeof(string) - header memset = ctypes.cdll.msvcrt.memset # For Linux, use the following. Change the 6 to whatever it is on your computer. # memset = ctypes.CDLL("libc.so.6").memset print "Clearing 0x%08x size %i bytes" % (location, size) memset(location, 0, size)
Let’s see it in action.
secret = "my secret password" zerome(secret) # Clearing 0x019b8484 size 22 bytes print repr(secret) # '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
As you see here, we find the location and size of the string, and zero it out. Note that this may not work in something other than CPython (the main implementation).
Related posts:








Please *don’t do this*. Please use the APIs provided by your operating system to securely wipe memory.
There’s nothing wrong with using memset.
The only reason why Windows provides a SecureZeroMemory is because C compilers can optimize it out in a C program. It isn’t even available prior to windows 2000.
> There’s nothing wrong with using memset.
Ah, I (mis)remembered SecureZeroMemory doing more work than just guarding against compiler optimization.
Are you familiar enough with the internals and intricate behaviors of Python, OS swap, hibernate, sleep, etc. to guarantee that this will wipe the variable, even if it’s been written out to disk?
Edit: I’m thinking something like this:
1. A page of physical memory is allocated.
2. Clear-text password is stored in that page of physical memory.
3. That page is swapped to disk.
4. The code to clear the password executes.
5. The page containing the clear-text password is swapped from disk into physical memory.
6. The clear-text password is scrubbed from physical memory.
I don’t think there’s any guarantee that the clear-text password will also be scrubbed from the swap file.
Likewise, I think this solution is insufficient if step 3 above is replaced with: the program crashes and dumps core; the OS is put into hibernate mode; etc.
In the general case, your password will not be swapped out to a page file needlessly.
You can use VirtualProtect with PAGE_NOCACHE on the page the memory resides on to ensure this. But this is really beyond the scope of the article.
I know of no OS API which automatically takes care of the situations that you outlined above.
Comments were nesting too deep, so starting afresh:
> In the general case, your password will not be swapped out to a page file needlessly.
Right, but one never knows when the password will be swapped out, or the program will dump core, or the system will go into hibernate, or…
> You can use VirtualProtect with PAGE_NOCACHE on the page the memory resides on to ensure this. But this is really beyond the scope of the article.
I’m not trying to be argumentative, but your solution doesn’t fully mitigate against the scenarios listed at the top of the article. So I’d say it _is_ in scope.
> I know of no OS API which automatically takes care of the situations that you outlined above.
That seems correct. My memory was wrong.
This solution actually does help. If you zero out the memory as fast as you can, the chances of the memory being swapped out is practically zero.
If instead you leave the password out there, and continue using your program for a couple hours then there’s a high possibility it will be swapped to disk.
Nice, thank you..
Since this is a security issue you’re discussion, thinking about ‘the chances’ of %s is not enough. Since the scenario is likely to include another program trying to read your process’ memory, you have to think of a malicious system.
Another program running alongside could play with timing issues, memory availability, paging, etc… Therefore, if you want this to be secure against the threat you are defending against, you have to consider these issues.
Security is always an issue of chances of % and convenience.
Take the lock on your door for example. It is not 100% secure, but its mostly secure. There’s always a chance that someone may be strong enough to smash it.
Another example would be the encryption key size. Why use 256 bits? Why not use 1 MB? Convenience, and the probability that whoever is cracking your key does not have a giant server farm or futuristic computers.
What about you just secure the swap itself by encrypting it?
At least OS X and Linux do support that, no idea about Redmond OS though.
Also encrypting your harddisk partition as such might help…
IMHO these security decisions should be left to the user and not the program at hand.
If you do think you should provide something “secure”, why not make the auth system pluggable and offer something really secure like one-time auth or whatever you feel like?
I’m not sure why people keep questioning this method. It is a standard practice to clear strings in memory when you are done with them in programs written in C/C++, and I show how this is possible in Python.