简体   繁体   中英

How to secure application specific passwords for gmail

We are switching from exchange to google hosted mail in the next couple of weeks and I'm trying to figure out how to setup email so we can send from inside django apps

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST='smtp.gmail.com'
EMAIL_HOST_USER='someone@example.com'
EMAIL_HOST_PASSWORD='16characters'
EMAIL_USE_TLS=True
EMAIL_PORT=587

So these are my email settings, and the part that bothers me is that the 16 character application specific password is soon to be committed to our git repository.

If I try to use this pw on the web frontend, it tells me not to use the application specific pw, but to use my account password. This is good, at least the web interface isn't going to let them in. But what else does this allow access to/thru? There were no restrictions placed on this key when it was created (there is no way to place restrictions on it, just a way to "name" it) So it seems like someone could use this key with an android phone and have full access to my account, completely defeating the purpose of 2 factor authentication.

So, how do you manage to use google as an email provider when your apps are sending bug reports (for 500s) or alerts to other people? All the smarthost setups I've seen require the username/password too, so it keeps it out of the repository, but doesn't actually fix the problem.

Right now it looks like I have to purchase an additional "user" from google and create the ASP for that user to send the emails, if I want to keep my account secure.

PS: just borrowed a different phone and proved it will indeed give them access to my account as expected. Seems like the ASP maybe needs the ability to node lock it to a specific IP or there needs to be phantom accounts for sending or something...

If you consider your hosting environments to be secure, you could follow the approach of storing the login and pass in environment variables. This is considered by some to be a best practice: http://www.12factor.net/config (and it appears to be growing in popularity).

Then in your settings.py:

  #If you want loud failures, usually the best
  EMAIL_HOST_USER = os.environ['EMAIL_USERNAME']
  EMAIL_HOST_PASSWORD = os.environ['EMAIL_PASSWORD']

  #If you want quiet failures, usually not a good idea
  EMAIL_HOST_USER = os.environ.get('EMAIL_USERNAME', None)
  EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_PASSWORD', None)

How you set the environment variable depends on your setup, but it is usually very straight forward.

This approach has the advantage of keeping secrets out of the git repo, so you can add new collaborators to the project without fear that they're going to take over your AWS/email/etc account

Another option would be to create a file in your filesystem, store credentials in there and set read/write permissions for users and groups. This would leverage permission tools of Unix-based systems.

Then in the settings.py file read them. It would look something like this:

from configparser import RawConfigParser

config = RawConfigParser()
config.read('/pick/location/file.ini')

[...]

EMAIL_HOST_USER=config.get('email_service','EMAIL_USER'),
EMAIL_HOST_PASSWORD=config.get('email_service','EMAIL_PASSWORD'),

More info here

PS: Would this be more secure than storing credentials in environment variables? Hard to say, let's see what other users think

Hope this helps, ciao!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM