Avoid storing passwords in plaintext for IMAP access via Python
Question: I'm trying to write a script that helps to clear IMAP inboxes, and I'm running
into a problem with passwords; namely, that to get access to the server I need
to have access to the plaintext. I've checked, and my mailserver isn't showing
MD5 as an available method (otherwise I could use `IMAP4.login_cram_md5`). How
do I go about accessing the server without plaintext passwords?


Answer: You can check the authentication methods available like this (I'm using
`IMAP4_SSL`, use `IMAP4` if you want an insecure connection, but I don't
recommend ever using non-SSL connections if you have the choice).

    
    
    import imaplib
    imap_server = imaplib.IMAP4_SSL("imap.server.com")
    print "\n".join(i for i in imap_server.capabilities if i.startswith("AUTH="))
    

You can then write an authentication object that can be passed to
`imap_server.authenticate()` for your chosen method. [This bug
report](http://bugs.python.org/issue13700) happens to have some examples of
its use and [this SO
question](http://stackoverflow.com/questions/7963820/gmail-imap-
authentication-imaplib-authenticate-takes-exactly-3-args-4-given) shows
someone authenticating via OAuth to Gmail.

If the server doesn't provide any authentication methods other than plaintext
passwords, or you can't / don't wish to support them, then storing the
password in a form where you can recover the plaintext is unfortunately
unavoidable. You could encrypt it in some form (e.g. AES using
[PyCrypto](https://www.dlitz.net/software/pycrypto/), example
[here](http://stackoverflow.com/questions/5778304/simple-example-
aes256-crypt)), but the encryption key is still going to be stored somewhere
unless you want to prompt the user each time (in which case you might as well
just prompt for the password anyway). I would suggest at least some trivial
obfuscation, such as Base64 encoding, just to prevent someone idly glancing at
the code or config seeing the password in the clear.

**EDIT:** One other point which might be obvious is to make sure that if you
do need to store plaintext passwords, you never store them in a file which
needs to be world-readable. For example, don't ever hard-code them in scripts
even if it's just a quick script which has all its other settings as global
variables or similar. Instead, try to make sure the password is in a separate
file which can have OS-specific permissions restricted as required.

