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!
Related
I am using CFLDAP in a ColdFusion application.
Currently, the SERVER, USERNAME, and PASSWORD are hard-coded in the application.cfc as application scope variables.
<cfscript>
application.ldapserver = "servername";'
application.ldapuser = "username";'
application.ldappwd = "password";'
</cfscript>
Later in my code, I am using CFLDAP:
<CFLDAP ="GetLDAPinfo" action="query"
server = "#application.ldapserver#"
username = "#application.ldapuser#"
password = "#application.password#"
....
</CFLDAP>
How can I get around using a hard-coded username and password ?
I was hoping to find something to configure in the ColdFusion Administrator similar to how e-mail is set up, but I didn't find anything.
Thanks.
Environment variables are commonly used for storing credentials on a server. Maybe this article will help: Reading Environment Variables In ColdFusion
Using the environment variables approach with plain text files is an accepted practice. You don't store that file in source control, but manage the per-environment settings in a secure location.
Local devs get local credentials (ideally unique per developer), but they don't see credentials for higher environments. Those should only be accessible by the appropriate users.
Here's an example of using .env files with NodeJS.
Alternatively, you could store the credentials in the database and retrieve them on application start. But even then, do the local developers have access to that environment's database? And you can always dump the application scope to view the values. Or you could use something like AWS Secrets Manager, but I don't know how well that works with non-AWS systems.
Since the current credentials are hardcoded, they'll always be in source control history. Make sure
you're rotating those credentials as part of this effort
creating credentials per environment
rotating them all on a regular basis
By seeing this answer I learned that Google blocks certain apps to connect, due to "lack of application of modern security standards" in those apps, and I can make Google allow my account to connect from such apps - I must do that explicitly.
This was due to an issue in Django mailing:
send_mail(
u"Message",
render_to_string('template.txt', {'data': data}),
settings.EMAIL_HOST_USER,
[dest['address'] for dest in settings.FORM_DESTINATIONS],
html_message=render_to_string('template.html', {'data': data}),
)
And my EMAIL_ settings involving a #gmail.com account (neither SSL/465 or TLS/587 worked).
Does this mean Django 1.7 has an insecure mailing mechanism? What does "secure" mean in this context and what mailing standards is Django not applying?
Edit Even when I provided context for this question (a pointed answer and related links/docs) perhaps some readers may not find where does Google talks about "secure"/"insecure" applications. By entering here using your google account credentials there's an option telling about "less secure apps" which lead to this page, which has a "More Info" link, pointing Here (this link does not need authentication).
Sending email via SMTP with Django requires you to store you password in plain text on your server. Apparently, Google considers storing the password in plain text a security risk and wants you to use either OAuth 2.0 or two factor authentication with application specific passwords. See
http://googleonlinesecurity.blogspot.de/2014/04/new-security-measures-will-affect-older.html
It is up to you to decide whether you consider storing the email password in plain text on a server a security risk. Keep in mind that you usually store your database password in plain text too, so when an attacker is able to read your application settings, it is pretty much game over anyway.
I would suggest enabling two factor authentication and using an application specific password, especially if you use that Google account for more than just sending mail from your server.
I'm thinking about migrating one of my django application to meteor. But there is one question I'm trying to answer before doing this: How does Meteor encrypt a password? (with the account-password package?)
In my case, I used the default django password encryption:
Django provides a flexible password storage system and uses PBKDF2 by default.
The password attribute of a User object is a string in this format:
<algorithm>$<iterations>$<salt>$<hash>
So my passwords are stored like this:
pbkdf2_sha256$12000$Z0rof3EQy1p2$wezcf334ytyBm12CPcdlNZLrkWYkaQklk4wHt5jxgWE=
Is it impossible to make Meteor adopt the same scheme so as my current users can continue to use my application without resetting their password?
accounts-password uses SRP to authenticate users. This was mentioned in the blog post for meteor 0.5:
Support for the Secure Remote Password protocol. Developed at Stanford, SRP lets a user securely log in to a server without ever sending that server their unencrypted password. The kind of high-profile security breaches at LinkedIn and Pandora earlier this year are impossible with SRP. Instead of asking every application developer to safely store passwords, we've baked the very best technology right into Meteor Accounts.
It's also discussed a little bit in this recent video. Side note - it's interesting that they are considering adding bcrypt in the future.
So for now, the good news is that meteor does not store password-equivalent information in the database. The bad news is that your users will need to reset their passwords if you choose to migrate your framework.
I'm looking at scripting parts of my workflow, which involves interacting with some web-services via SOAP and XML-RPC queries. I'm scripting using bash and python.
I need to authenticate against these web services, and I'd ideally like to do so
without having to type in my password for every request (typing it once per login would be fine)
without hardcoding it in my scripts
without storing it in plain text anywhere on disk
in a way which isn't specific to one flavour of Unix
The OS X keychain (via the 'security' command) is one possible solution for the Mac OS X case, but there are issues with using it from a script as noted in a related question, and I'm hoping for a more general solution.
I'll have a go at answering my own question.
I could do either or these, or a combination of both:
Store the password in a file with 600 permissions on an encrypted partition
Store the password in a file encrypted with a passphrase, and read that passphrase into an environment variable interactively, once for every shell I'll be calling the script from
Combining these approaches seems sufficiently paranoid.
I'm trying to wrap my head around your architecture, so I'm not sure which thing you are trying to authenticate. Are you trying to:
- check the web service caller
- check the web service provider
- both
And is the thing being authenticated a human using a program or the server itself?
And do you have to pass the service calls around and authenticate them at multiple points or is this strictly point to point?
And what is your assessment of risk? What bad stuff is the authentication preventing?
If you do your proposed #1, your authentication problem moves from the message to the server - if your server is physically protected and your authetication credentials to the OS are "strong enough" you're probably decently protected in where you've stored the password.
I'm confused on #2 - if you are reading in the passphrase interactively, why not read in the password interactively and not store the password at all? If the passphrase unlocks the password, handling the passphrase should be as careful as if you are handling the password.
The bigger concern with any password is where is it going, and how is it protected along the way. Using passwords within the web service will be risky if you are sending your web service messages in the clear. Also where are passwords checked on the other end, and how are they distributed to the server for storage for #1 and #2? This is just stuff to consider for any password based authentication mechanism.
Also - how often should passwords be changed and do you have a procedure for it?
And how much do you repeat the password? If you have exactly one password shared across every machine, the risk is much higher than a different password for each server/script or user, since you can disable them one at a time.
Maybe a technique like ssh-agent.
I need to make a simple knowledge-base type application to use in company internal network. To make it simple and fast to use for end-users I would like to skip all the login in part (as it will be only visible to internal network users who we trust anyway) and automaticly pull the domain user name from the user and put it into the database (don't want people to waste time manually entering their name; the littler time they waste using the app, the higher chance they will actually use it).
So, is it possible to get that kind of information on a server? Do windows browsers send it in some headers that I could trust to be there?
If you are using IIS and Internet Explorer, you could turn on 'Integrated Windows Authentication' (NTLM authentication). This causes IE to automatically authenticate the user using your domain infrastructure. After automatic login, you can access the user name using the environment variable LOGON_USER. There is also a module for Apache (mod_ntlm) for this purpose, although I don't know its status.
Maybe you could event try to implement NTLM authentication yourself, but this will certainly be a lot of work.
Other than that, there seems to be no way since no reasonable browser will send the user name...
EDIT: It seems that python-win32 extensions or python-ntlm could do the trick, check out this thread. You still have to integrate it into Django, though.