I want to have Python send a mail automatically after certain events occur. In my script I have to enter a password. Is there any way to encrypt my password and use it in this script?
Please give an example as I am not an expert in python. I have seen few answers on this topic but those aren't discussed completely, just some hints are given.
The script needs the password in plain text to send the email. You could encrypt it, but then you also have to provide a way to decrypt it on the fly.
Let me illustrate with some pseudo code.
Right now you have something like this:
password = 'supersecret'
send_mail(password=password)
If you encrypt the password it would look something like this:
encrypted_password = 'kasdjhfkauedsjflh'
encryption_key = 'allyourbase'
send_mail(password=decrypt(encrypted_password, encryption_key)
As you can see, it doesn't really make any difference.
Encryption basically tries to rely on one (and only one) secret.
That is, one piece of data that is known to those who want to communicate but not to an attacker.
In the past attempts have been made to e.g. (also) keep the encryption algorithm/implementation secret, but if that implementation is widely used (in a popular cryptosystem) those attempts have generally fared poorly.
In general that one secret is the password. So that even if the attacker knows the encryption algorithm, he cannot decrypt the traffic if he doesn't know the password.
As others have shown, encrypting a password and giving a script the means to decrypt it is futile if the attacker can get hold of the script. It's like a safe with the combination of the lock written on the door.
On the other hand as long as you can keep your script secret, the key in it is secret as well.
So if you restrict the permissions of your script such that only the root/administrator user can read or execute it, the only way for an attacker to access it is to have cracked the root/administrator account. In which case you've probably already lost.
The biggest challenges in cases like these are operational.
Here are some examples of things that you should not do;
Make the script readable by every user.
Store the script where it can by read be a publicly accessible web-server.
Upload it to github or any other public hosting service.
Store it in an unencrypted backup.
Update: You should also consider how the script uses the password. If it sends the password over the internet in cleartext, you don't have much security anyway.
My way is to use the keyring, simply using yagmail you can have passwordless scripts by using the keyring (full disclose: I'm the developer of yagmail).
E.g. to send an email:
import yagmail
yag = yagmail.SMTP()
yag.send(contents = ["See picture below", "/local/path/to/img.png"])
To get this done, first install (below) and then register your email into the keyring once by using:
yagmail.register('myemail', 'mypass')
If you also put a .yagmail file in your home (~) folder containing your username, you can use yagmail.SMTP() in your script and safely login.
Install:
pip install yagmail # python 2
pip3 install yagmail # python 3
Ironically, I also have made gittyleaks, you can use it to discover username/passwords/email in a git repo, including all history :)
Related
I am writing a python script to login in my email, and I am using
M = imaplib.IMAP4_SSL('imap.gmail.com')
M.login('foo#gmail.com','123456')
however i want to let my friend use my script but i dont want him to know my password. I was wondering that is this possible?
In general, no this isn't possible, especially not if the idea is for your friend to run the script on their own computer. Your script needs to have access to the plaintext password in order to send it to the server. Whatever obfuscations you apply, anyone with access to run the script can do the same de-obfuscating as the script itself in order to retrieve it. If they have access to modify the script, they could even just change it to print exactly what you send to the server.
The only possible way around this is for you to control the full execution environment, and have the script run with different permissions than the user who can invoke it (using something like setuid Unix permissions, or even something as fully fledged as polkit). This is probably a prohibitive amount of effort compared to what you're trying to do.
ema=input("Enter your mail adress: ")
passw=input("Enter your password: ")
M = imaplib.IMAP4_SSL('imap.gmail.com')
M.login('{}'format(ema),'{}'.format(passw))
Instead of encrypt, you can use this. So your friend not have to see your password, he should enter his mail-password or you either. Or you can use getpass.getpass()
I know the best practise is to hash user passwords, and I do that for all my other web apps, but this case is a bit different.
I'm building an app that sends email notifications to a company's employees.
The emails will be sent from the company's SMTP servers, so they'll need to give the app email/password credentials for an email account they allocate for this purpose.
Security is important to me, and I'd rather not store password that we can decrypt, but there seems like no other way to do this.
If it makes any difference, this is a multi-tenant web app.
What's the best way in python to encrypt these passwords since hashing them will do us no good in trying to authenticate with the mail server?
Thanks!
Note: The mailserver is not on the same network as the web app
I've faced this issue before as well. I think that ultimately, if you are stuck being able to produce a plain-text password inside your app, then all of the artifacts to produce the password must be accessible by the app.
I don't think there is some encryption-magic to do here. Rely on file-system permissions to prevent anyone from accessing the data in the first place. Notice that your SSH private key isn't encrypted in your home dir. It is just in your home dir and you count on the fact that Linux won't let just anyone read it.
So, make a user for this app and put the passwords in a directory that only that user can access.
I would strongly recommend using BCrypt. There are lots of advantages to the algorithm, and most implementations handle all of these questions for you.
As described in this answer:
Bcrypt has the best kind of repute that can be achieved for a cryptographic algorithm: it has been around for quite some time, used quite widely, "attracted attention", and yet remains unbroken to date.
I've written up a detailed article about how to implement BCrypt in python as well as other frameworks here: http://davismj.me/blog/bcrypt
I've read so many answers and tutorials and post about push notification, I've managed the registration, creating the certificates p12 and pem files as well as apple provisioning just fine so my application knows how to receive push notifications (or at least it looks like it does)
Now I'm trying to set my server side - python/django.
I've uploaded the key & cert pem files into my server folder, following this answer here at SO. I'm getting an error when i try to ssl_sock.connect( theHost ) since the pem has a paraphrase, I've read many people saying just to remove the paraphrase but then isn't the whole security public/ private key is out of the window? and if using this approach do i need to remove the paraphrase from the pem file at apple as well? or the one i've downloaded to my mac?
To expand on meda's answer - think about this:
If you put a passphrase on certificate, you will need to hard-code the pass phrase somewhere in your django project, since it will need that passphrase to load the certificate.
If someone compromises your server, they have your certificate. "No problem!", you think. You've got a pass phrase, so they can't do anything with it!
Except they also have access to your source code.
So now they have your pass phrase, and your certificate.
So all you really did was add hassle for yourself, without any benefit.
Pass phrases on certificates make sense if the certificate is being stored among other shared assets, for whatever reason, or for high encryption concerns where the private key will ONLY be used manually, by an individual or group.
In all other cases, it's a complete waste of effort.
I used PHP to accomplish this but I can tell you about what I know:
Passphrase is just an additional encryption layer
SSL encryption alone is really secure.
If you want to remove passphrase leave it blank when you are prompt to enter one.
basically, I want to have a login box, and the option to remember the password next time you log in. I know there are encryption modules out there, but they require a password to work in the first place. is there a way to get the password the user used to log into the computer, and use that to encrypt the password for my application?
so in a nutshell, how do I store a password securely for later use.
I'm using python 3, and my program needs to be crossplatform.
Sounds like you need Keyring: https://pypi.python.org/pypi/keyring
There is no way out. If the application does not ask the user for a password, then it is not securely storing passwords, it's only doing... "things". In that case, don't give the user a false sense of security, use cleartext.
A notable exception is the GNOME login keyring (and equivalent on other platforms) not asking for a password, but it uses a trick: it encrypts data with your login password and decrypts them with the same when you enter it at startup.
If you are developing a web application with a local client, consider using OAuth instead of passwords.
You cannot get the password the user used to log in to the computer.
And, if you could, you would not want to store it.
In fact, the OS doesn't even have the user's password. The OS has a hash of it, and when the user logs in, it hashes what the user types and checks that it matches.
Also, if you ask the user to log in with their system password, any savvy user is going to immediately mistrust your app and refuse to use it. Make them create a password, and then login with that, not their system password. And don't save the password, save a hash, just like the OS does.
If you want to verify that they've been authenticated by the OS… well, you already know that, or they couldn't have logged in to run your app. (If you're building a network server that allows remote login based on local accounts, that's a different story, but it's not relevant to your use case, and complicated, so I won't get into it here.)
If you want to allow someone to "stay logged in", you don't do that by saving their password. Instead, you create some kind of hard-to-fake "session key" when they log in, and store that somewhere. They don't have to log in again until you destroy the session key (which you do when they log out).
The one exception to "never store passwords" is when you need to act as a "proxy" for the user to some other application that needs their password. A well-designed application will provide a way for you to proxy the login properly, but many applications are not well-designed. Web browsers have to do this all the time, which is why most web browsers have a "remember my password at this site" checkbox.
In this case, you do want to store passwords, ideally encrypted by the OS on your behalf (e.g., using OS X's Keychain APIs), or, if not, encrypted by you code using some key that's generated from the user's "master password" (which you don't store).
Unfortunately, there is no real shortcut to learning how to design for security—or, rather, there are all kinds of shortcuts, and taking any one of them means your entire system ends up insecure and all the work you put into trying to secure it ends up useless.
The easy solution is to use complete off-the-shelf solutions.
If you want to design things yourself, you need at least a basic grounding in all of the issues. Start with one of Bruce Scheneier's "pop" books, Secrets and Lies or Beyond Fear. Then read his Practical Cryptography on designing cryptosystems, and Applied Cryptography on evaluating crypto algorithms. Then, once you realize how much you don't know and how important it is, learn everything you need for your problem, and then you can think about solving it.
I have a Python script that is connecting to the database. To that, obviously, I need the password. I need to hide it somewhere.
My problem is that this code is stored in a folder that everybody who has access to the server can look. So, if I write this password encrypted in a file, in the code will appear the key to discover it and people can figured it out.
So, please, if anyone has an idea..
You're using a scripting language and accessing a database directly with a password. No matter what you do, at some level that password is going to be easily accessible. Obscuring it doesn't really buy you much.
You have to rely on the machine's security and permissions, and perhaps the database (restricting access from that particular machine and user).
Don't store the database connection credentials in the Python file at all. Instead, store them in a secure place, readable only by the user account that the script will run under.
For example, create a user account for running this job, and create a file in that user account's home directory (readable only by that user) called database.ini and put the database connection string and password there. Then use the Python ConfigParser class in the standard library to read the file in.
Then the job can be always run under that user account. You can also run it under your account by putting a database.ini file in your home directory with the correct credentials, but anyone who doesn't have the credentials cannot run it.
Check out this question. They suggest encoding the password in base64 (outside of the script) then including that string in the script and converting it back before you make the connection
Just to reinforce what Brian said, if a program runs automatically (i.e., without the opportunity to prompt the user for a password), any program that runs under the same user authority has the same access to any password. It's not clear what else you could do. Perhaps if the (trusted) operating system on the client machine could certify to the host that it was being accessed by a program run from a particular path, the host could be told "Only open the database to /var/lib/tomcat/bin/tomcat on appserver.example.com". If you accomplish all that, an attacker would have to compromise the tomcat executable to get to the database.
A more advanced idea is to do the mysql authentication manually. That is, learn the mysql protocol (it's a standard handshake with a challenege and a response) and do the procedure yourself. This way, you never send the password directly.