Python script with password security?

jisoo411
jisoo411 used Ask the Experts™
on
Hello,

I'm writing a Python script that will connect to a postgresql database using the psycopg2 library.  I'm getting around it pretty well but one concern I have is that when connecting to the database host, I have to hard code the username and password into the connection statement.  I would prefer not to do this and would like to somehow refer to an external file for this information and import that user account info then construct the connection string.  That way at least the username/password combo wouldn't be directly visible when looking at the Python code.  Any help or alternative ideas would be very much appreciated.

Example of the psycopg2 connection statement:
import psycopg2

conn_string = "dbname='mydatabase' port='1234' user='joe_shmoe' password = 'joespassword' host='hostaddress.com'"
conn = psycopg2.connect(conn_string)

Open in new window


Thanks,
Glen
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Walter RitzelSenior Software Engineer
Commented:
I'll start working on something similar. I'll have a script that will get one file with the following text:
dbhost = xxx.xxx.xxx
dbuser = xxxxx
dbpass = xxxxx

and it will encrypt the file with the simplecrypt module:
from simplecrypt import encrypt, decrypt
ciphertext = encrypt('password', plaintext)

Open in new window


Then I'll create a module that will load the file and decrypt:
from simplecrypt import encrypt, decrypt
plaintext = decrypt('password', ciphertext)

Open in new window


Module is here:
https://pypi.python.org/pypi/simple-crypt
Data Scientist
Most Valuable Expert 2014
Commented:
you could also store your keys/passwords as environment variables outside your application directory.

then use the os module to access the env vars your py script

import os
print os.environ['HOME']

Author

Commented:
Sorry for the late reply.  These both look like good potential solutions for me.  Here's some extra context as well, I'm developing this Python script on a Windows machine but it will run on a Linux machine.  The main purpose of this script is to pull CSV files into a local directory then load them into the postgresql database.  

With the environment variable method, will the os module work seamlessly between Windows vs Linux?  For instance, if I create the following environment variables on both Windows 10 and Linux:

UserName = Joe
Password = JoePassword
TempDir = C:\Temp (Linux would be something like '/usr/tmp/processing')

Would the os module refer to them in exactly the same way using the os.environ function call?  I.e. os.environ['TempDir'] would output C:\Temp when run on Windows and /usr/tmp/processing when run on Linux?

Thanks,
Glen
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

Author

Commented:
Looking at the os reference, it looks like maybe the getenv function would do this...

import os
print os.getenv('TempDir')

That gives me C:\Temp on Windows 10.  I'm guessing it will work in Linux since the reference says it works on most flavors of unix.  One follow up question though, setting an environment variable in Linux is typically temporary for the session.  Where would I set this to make it system-wide and permanent?  

Thanks,
Glen
Kyle HamiltonData Scientist
Most Valuable Expert 2014
Commented:
If you wanted to set the environment variable in linux permanently you could add it to the .bashrc file, or for a given user, add it to .bash_profile:

export TempDir=/usr/tmp/processing

Open in new window

(notice no quotes or spaces)
Kyle HamiltonData Scientist
Most Valuable Expert 2014

Commented:
here's another way:

if you wanted to keep those variables in their own file, you could make a .passwords file, with the export lines, then in your .bash_profile:

source path/to/.passwords

Open in new window


remember that every time you add an environment variable to a file, you have to either start a new shell, or source the file in which the variables are defined.

Author

Commented:
I'll be looking to set this environment variable permanently for all users.  It'll be a common variable utilized by all Python scripts being dropped onto the server and executed via cron or some other job scheduler.
Kyle HamiltonData Scientist
Most Valuable Expert 2014

Commented:
The I would put it in a .passwords file that will be dropped on whatever server you need in some predetermined directory.


in .passwords
export NAME="name"
export PWD="password"
export DIR=/your/temp/dir/

Open in new window


In your script which gets triggered by cron, add the source line:

source /path/to/.passwords

Open in new window


and in your python script:

import os
password = os.getenv('PWD')
username = os.getenv('NAME')
tempdir = os.getenv('DIR')

Open in new window

Author

Commented:
That would work if I developed on a linux machine, unfortunately my workstation is Windows while the environment I deploy my code to is linux.  It sounds like simply adding the export statements to the .bashrc file would suffice and would eliminate any need to that source line in my python script, is that correct?
Kyle HamiltonData Scientist
Most Valuable Expert 2014

Commented:
i assumed your cron would run a bash shell script. you would put the source line in the shell script.

if you put the variables in .bashrc, you will need to do that for every server you deploy on.

you could still automate it with a script that appends to .bashrc.

it's a half a dozen, or six thing. (i can never remember that expression right :)

many ways to skin a cat...

Author

Commented:
Very true.  Thankfully we're only dealing with 1 or 2 linux servers for the long term so we're good there.  I just tried to put in the export statements, I restarted bash and did a "printenv" to verify that they got set (which they did).  But after I closed my putty session and started a new one, the exports disappeared.  Somehow they became session-specific and not permanent.  I performed the following steps:

1.  vi ~/.bashrc

2.  Added line: export temp_dir="/home/ubuntu/tmp/"

3. exec bash -l

Open in new window


Is there something I'm missing?

Author

Commented:
Searching around google, I see a file called "/etc/profile" being mentioned.  When I look at the file on my linux box I see that it's executing ". /etc/bash.bashrc" as well as "/etc/profile.d".  Should I be putting these export statements in "/etc/profile" instead?

Author

Commented:
Nevermind, "/etc/profile" is apparently a root directory and I don't have permissions to modify that :/

Author

Commented:
Looks like it's the .profile file in the home directory that keeps the settings permanent.  I set up the temp_dir export statement in there and closed out my session window then logged back in and the printenv command still shows the variable.  Hopefully that's it.
Kyle HamiltonData Scientist
Most Valuable Expert 2014

Commented:
glad you got it working.

typically the file is in the home directory, called .bash_profile

cheers.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial