Connecting python program to mysql safely - python

I want to connect to MySQL from my python program using MySQLdb.
I am worried because I need to put username and password in the .py in order to connect to MySQL database, as well into inno setup.
Couldn't anybody find the user name and password and get access to my database? How do I solve this problem? Do I make a sql user with limited access somehow? (I am new to html/css/MySQL).

First, make sure your MySQL user/password is different than your username and password.
Next, make a file called, say, config.py and place it in a directory in your PYTHONPATH:
USER='zzzzzzzz'
PASS='xxxxxxxx'
HOST='yyyyyyyy'
MYDB='wwwwwwww'
Change the permissions on the file so only you (and root) can read it. For example, on Unix:
chmod 0600 /path/to/config.py
Now, when you write a script using MySQLdb you'd write
import config
connection = MySQLdb.connect(
host = config.HOST, user = config.USER,
passwd = config.PASS, db = config.MYDB)
So your username and password will not appear in any of your scripts.
You could also put config.py in an encrypted directory, and/or on a USB thumb drive, so the file is only accessible when the drive is mounted.

Related

How to deploy/store tkinter sqlite database in a server?

I have a login interface, I used tkinter and sqlite3 as database, everything works fine, in my data base stored locally in my PC I've created an username and password which i use to login, I would like to know if there is a way to store only my sqlite.db in a cloud or some server and i can still be able to login with my tkinter interface in any computer using my databese in the cloud.
this is what im using to connect my sqlite database locally and works smootly.
conn = sqlite3.connect('login_file.db')
c = conn.cursor()
user = entry_usuario.get()
contra = entry_contrasena.get()
c.execute('SELECT * FROM superusuario WHERE usuario = ? AND password = ?', (user, contra))
if c.fetchall():
messagebox.showinfo(title='login correcto', message='usuario y contraseña correctos')
else:
messagebox.showerror(tittle=None, message='Contraseña Incorrecta')
c.close()
Psdt: I was trying to use firebase authentication to link with my tkinter login interface, but i wasnt succesful with it (i dont know how to replace it), maybe i should use another server?, any advise please let me know, thanks in advance have a good day
sqlite is a file based database, with no in built network server. So your application needs to access it as a file in a known location.
The only way to do this without a server side function is to host it on a remote network drive - and mount it on your pc; but to do that you leave your data exposed since sqlite data bases aren't password protected in any form - anyone could download the database and open it.
To protect it you would need to implement a network server (maybe on an AWS server - or similar) which gave protected access and exposed the data as a REST API, or even better, don't use sqlite if you want a remote database.

Postgres database security: what to store in environment variables?

There is a Postgres database that I connect to with SQLAlchemy.
I currently have the database's connection parameters (database name, host, port, username, password) all hard coded in the Python file. I want to change that.
I read here that one should store these parameters in environment variables. Of the five connection parameters, what should I store in environment variables?
Obviously I will store password, but should I additionally store username and host? What is the convention here?
Putting settings in environment variables isn't just about security. It's also about flexibility. Anything that's likely to change between environments is a good candidate to be put in environment variables.
Consider your database. Is it likely that the host, user name, and database name might be different on different environments? I suspect so. Many projects might use a database on localhost or on a Docker image called db in docker-compose.yml in development, and to use a dedicated database server or hosted database in production.
A common pattern is to encode your entire database connection string in a single environment variable DATABASE_URL. The format¹ is something like
<engine>://<user>:<password>#<host>:<port>/<database>
For example, you might use something like
postgres://db_user:password#localhost/app_db
Many database libraries, including SQLAlchemy can connect to databases using this single string directly.
¹This is a specialization on regular URL syntax.
Why hardcode anything? Just move all of these parameters to environment variables.
One of the way to do this will be as below from security point of view.
Assuming that we classify password as sensitive data and we want to encrypt only the password. Rest information can be either in environment variables or into the config files.
1) Have a random value based salt that is specific to the server generated at the time of encryption program invocation. This value is saved into file. Lets call it salt.bin
2) Change permission of the salt.bin file such that it is readable only operating system user which will run your program.
3) Have security personal/entrusted personal enter password to the encryption program and saved the encrypted value into a file. Lets call it db_config.bin.
4) Change permission of the db_config.bin file such that it is readable only by operating system user which will run your program.
Now during program execution time, let program read salt.bin file and db_config.bin file. Decrypt db_config.bin by using salt.bin. Program uses this password along with config files values for host, port, and other details to connect to database .
All of above can be accomplished with python.See here.

Connecting remotely to a MongoDB database without storing password in plaintext

I am trying to remotely connect to a MongoDB database but don't want to store the password for the database in plaintext in the code. What's a good method for encrypting/decrypting the password so it's not available to anyone with the source code? The source code will be on GitHub.
I'm working with Python and PyMongo for connecting to the database. The database has authentication enabled in the mongod.conf file. The database is hosted on a Ubunutu 18.04 instance running in AWS.
It would also be nice to have the IP address of the server encrypted also as i've had security issues before with people accessing the database due to the code being available on GitHub and then presumably scraped by bots.
My current URI looks like this
URI = "mongo serverip --username mongo --authenticationDatabase admin -p"
I would like the IP address and password to be encrypted in some way so that the password and IP aren't publicly available in the source code.
There is only and and simple way:
If you don't want the password and the server name to be included in your public repository don't write it into a file that is pushed into that repository.
One way to do so would be to create a config file for secret data and add it to the .gitignore file. At run-time open the config file, read the secret data from it and use it in your script.
Another way would be to provide the secret data (password an server name) as command line parameters to your script.
Any other way that "encrypts" (obfuscates) the password is insecure as long as the repository contains also the obvious or hidden key. This can be decoded with a little effort.
All the options provided by Robert makes complete sense. However, I would like to give one more:
You can store username and password under your environment variables under .bash_profile and access the corresponding env var in python.
Example: -
In .bash_profile:
export USRNM='myname'
export PASS='password'
In python:
import os
username = os.environ.get('USRNM')
password = os.environ.get('PASS')
This way, username and password will not be present in your project directory and cant be accessed by looking at the source code.
PS: Further encryption can be added to the password string stored in .bash_profile.

Connect to SAP HANA by using HDODBC driver without UID and PWD in code

I am trying to connect to SAP HANA data source via Python code.
I did manage to establish a connection. I have a raw data string in my code as follows:
db = pyodbc.connect(driver = '{HDBODBC}', UID='username', PWD='password', SERVERNODE='server:<port_no>')
However, I do not want the UID and PWD fields in my string.
I did set up a DSN connection using the ODBC manager on Windows. But, I still need to enter my username and pwd as follows:
db = pyodbc.connect(DSN="MyDSN", UID='username', PWD='password')
How can I set up a connection without my UID and PWD being displayed in the python code?
I have been looking for the same option to use hdbuserstore key to be used with python for connecting to SAP HANA. Looks like HDB client hdbcli has that option added now.
The user that is running the script needs to have the PYTHON_PATH set to the location of the hdbclient or in the script you can have the path set.
from hdbcli import dbapi
conn = dbapi.connect(key='hdbuserstore key',CONNECTTIMEOUT=5)
conn.isconnected() will return True if the connection is successful.
hope this is helpful for someone!
Be carefull with parameter CONNECTTIMEOUT=5.
from hdbcli import dbapi
conn = dbapi.connect(key='hdbuserstore key',CONNECTTIMEOUT=5)
This means NOT 5 second because it is in ms. Toke me long time to find out this problem.
connectTimeout, Timeout in milliseconds
0 (use system's TCP/IP socket connection timeout)
Aborts connection attempts after the specified timeout.
for example create file in a secure place and load connection setting (UID, PWD encrypted password (heshkod)) from this file
This requirement is relatively easy to fulfill.
The SAP HANA client software (the package that also contains the ODBC driver) provides a program to set up a secure store for logon data: hdbuserstore.
In my blog I explained how that works in detail.
The core steps are
create the hdbuserstore entries for the operating system user that should use the application.
Syntax: hdbuserstore SET <KEY> <ENV> <USERNAME> <PASSWORD>
Example: hdbuserstore SET millerj "localhost:30115" JohnMiller 2wsx$RFV
The hdbuserstore key needs to be referred to in the ODBC connection.
To do that, fill the SERVERNODE parameter with #<KEYNAME> instead of the actual server address.
For the example above, the value would be #millerj.
And that's really all. The ODBC driver will try to look up the hdbuserstore entry provided upon connection and use that to connect to the database.
Check the documentation for more information on this.

Database password requested when running "manage.py test"

When I try to run
manage.py test
a database password prompt shows.
Previously, tests would run without me having to enter the db password manaually.
I just updated my database to postgres 8.4. I assume it's some setting I'm forgetting.
How can I configure it to run tests without asking for the password?
Additional Info:
I created the database with the user 'postgres', but am accessing in django with the user, 'postgis'. I checked the permissions of these users, and they are the same.
When running the test the db and tables get created fine (no password requested).
It's only when it installs 'Custom SQL' that the password is requested.
RESOLUTION
As Carl pointed out the ~/.pgpass file [*nix] and %APPDATA%\postgresql\pgpass.conf (where %APPDATA% refers to the Application Data subdirectory in the user's profile) [windows] allows you to configure databases so you don't need to enter a password each time.
See the postgres documentation: The Password File
I checked my configuration and it looks like this file was/is auto-created. I updated my password file and now django tests run without the need to manually enter a password on each custom sql installation.
Django tests use a different database; your DATABASE_NAME setting with "_test" appended. My first guess would be that somewhere in your Postgres authentication config (either in pg_hba.conf or in a ~/.pgpass file), you are allowing access to DATABASE_NAME with no password, but you don't have the same config for DATABASE_NAME_test.
I assume it's some setting I'm
forgetting.
Not trying to make a fool out of you, but sometimes simple solutions are overlooked:
Did you set the DATABASE_PASSWORD setting in your settings.py file?

Categories

Resources