I'm in the process of building an app to let users sign up, connect their many email accounts (like Gmail) to the site, and allow email-related activities... like sending an email (please don't ask or say "oh the user can just go to their mail clients or Gmail tab to do that!", i know i know.) You could say i'm making an online mail client. I tried to explore how ThunderBird, Outlook, or Apple's Mail client manage login credentials, but I couldn't quite figure it out.

The Approach:

When they submit their email's login and password for the first time to my app, we do the following:

  1. salt the username and password with a 30 to 40 char key (different for every user)
  2. use AES-256 encryption (username and password have different keys stored elsewhere)
  3. then store the encrypted username and encrypted password

I'm aware of the theories, industry-recognized approaches to use one-way hashes and the many open source libraries, but my app needs to submit the user's email credentials, say, every time they want to send an email.

Here is a sample output of a user's email settings record stored in the database (using Rails):

#<EmailSetting id: 10, user_id: 3, 
username: "{\"v\":1,\"adata\":\"\",\"ks\":256,\"ct\":\"E1M3+Eza9w5yNIoBVS...", 
password: "{\"v\":1,\"adata\":\"\",\"ks\":256,\"ct\":\"8N/Ylh7IGiHKDz1QM7...", 
outgoing_server: "smtp.gmail.com", 
incoming_server: nil, 
email_connection_type: nil, 
outgoing_port: 587, 
outgoing_authentication_type: "plain">

I'd like to make sure that if this database is ever compromised, i can protect the user's as best as i can while providing a service.

Question: is this strong enough to protect email login credentials? Is there anything i might be forgetting in protecting the database table?

  • I guess now instead of having to keep the username and password safe you have to keep the username AES key and password AES key safe. As long as you can do that, looks ok. – hft Sep 21 '15 at 2:12
  • 4
    When possible, you should be using things like the Gmail API which is based on OAuth 2.0, and doesn't require storing user passwords. You should if at all possible avoid storing user passwords. – Stephen Touset Sep 21 '15 at 3:33
  • Your server must be able to recover the plain password from the DB (using your process instead of suggested API ones) so you won't be able to block an attacker. You might put a secret in your web server (outside the DB) required to get the passwords back, but that's a tiny mitigation, not a solution. – Xenos Jul 20 '18 at 15:51

As a service provider, You should never, never store passwords in a way that they can be retrieved. Comparing yourself to an email client is a bad way to think of it, and doesn't take into account an attackers perspective. Compromising a Thunderbird install only gets an attacker one or a few sets of credentials. Compromising your service could get an attacker your entire customer bases credentials.

As other commentators have pointed out, you now have the job of protecting the password set. If that's compromised and DB access is possible, you've now leaked ALL of your customers gmail usernames and passwords. If you have a lot of customers, this is a gold mine. Don't underestimate the power of dedicated attackers.

As Stephen Touset points out, you should be using the GMail API, which doesn't reveal passwords, but uses revocable tokens using the OAuth2 framework. If you were compromised, the tokens could all be revoked. That's not possible if the attacker were able to get all the username/password combos.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.