Storing passwords in scripts?

Question: I have a script that logs into service X, and right now I just have my password as a plain text string in my script. Seems like a bad idea. What would be better?

Answer: It depends on what your concern is.

I want it to magically work for only me

If you are concerned about someone who gains access to running your script on your computer, there’s nothing you can do. If your script can access a resource without asking you for your password, that means it knows everything it needs to know to get your password (either it’s in plain text or it knows everything it needs to decrypt it from somewhere). An attacker can read that program and learn those secrets, or simply edit your code to print the password before it uses it to authenticate.


...
username, password = secret.deobfuscate_credentials()
print("credentials:",username,password) #attacker adds this line
service.authenticate(username,password)

Relevant XKCD #1200

Just set your screen to lock after x minutes.

My script needs many passwords and I only want to type one

This is more reasonable. You need something that can securely store many passwords, and requires a password to log into that. There are various vaults that exist, like ansible-vault that will encrypt your file full of passwords for you.

I want to be able to share my code without sharing my password

This is the most common case. When writing a reusable, publishable module that uses an API key or authenticates to a personal account, I put that info along with any me/my computer specific data in a secrets.py. Then I just import it from my script. If using git, I git-ignore secrets.py and create a secrets.py.template which shows the expected structure of the file with instructions to fill it out and delete the .template from the file name.

If you want, you could delete the .py file after running it once, so there is a .pyc. This would be the easiest obfuscation technique that raises the bar for a casual snooper.

Leave a Reply

Your email address will not be published. Required fields are marked *