Securing Credentials in Python Apps

Securing Credentials in Python Apps

Post Stastics

  • This post has 1250 words.
  • Estimated read time is 5.95 minute(s).

Python has become a very popular language for software development. Over the decades since it was first introduced, the language has slowly grown and matured while keeping its ease of use and shallow learning curve. This has made it the go-to language for much of the AI and ML communities and many web applications have been built on Python. Many of these applications must use or manage user and API credentials such as passwords and API keys. Today, we will look at some of the methods used to store credentials in Python applications. Which method you choose depends on your specific requirements. My aim here isn’t to tell you which to use but instead, to introduce you to some of the methods in common use.

Hashing

Hashing Passwords: One of the most secure ways to store passwords is by hashing them. Hashing is a one-way function that transforms plaintext passwords into a fixed-length string of characters. Python provides various hash functions such as SHA-256, SHA-384, and SHA-512, which can be used to generate a hash of the password. Once the password is hashed, it cannot be reversed to its original form, making it difficult for attackers to obtain the actual password. Here’s an example of hashing passwords in Python using the hashlib module:

Here’s an example of hashing passwords in Python using the hashlib module:

import hashlib

password = "MyPassword123"
salt = "abcd1234"  # random salt value

# add salt to the password
salted_password = password.encode() + salt.encode()

# generate hash of the salted password
hashed_password = hashlib.sha256(salted_password).hexdigest()

print(hashed_password)

Key Derivation Functions (KDFs)

Using Key Derivation Functions (KDFs): KDFs are designed to slow down the hashing process and make it more time-consuming, making it difficult for attackers to guess the password. The most common KDFs used in Python are PBKDF2 and bcrypt.

Here’s an example of using PBKDF2 in Python:

import hashlib
import os

from pbkdf2 import PBKDF2

password = "MyPassword123"
salt = os.urandom(32)  # generate a random salt value

# generate a key using PBKDF2
key = PBKDF2(password, salt).read(32)

print(key)

Encrypting Passwords

Encryption is another method of securing passwords in Python applications. In encryption, the password is encrypted using a key, which can be decrypted to obtain the original password. The most common encryption algorithms used in Python are AES, DES, and RSA.

Here’s an example of encrypting passwords in Python using the cryptography module:

from cryptography.fernet import Fernet

password = "MyPassword123"

# generate a key
key = Fernet.generate_key()

# create a Fernet object with the key
fernet = Fernet(key)

# encrypt the password
encrypted_password = fernet.encrypt(password.encode())

print(encrypted_password)

Using a Password Manage

A password manager is a software application that stores and manages passwords for various online accounts. Password managers use encryption to store passwords, and users only need to remember one master password to access all their other passwords.

Python has several third-party password manager libraries, including LastPass and KeePass.

Storing Credentials in LastPass:

To use the LastPass Python library, you will need to install the lastpass module:

pip install lastpass

Here’s an example of how to store and retrieve credentials from LastPass:

import lastpass

# create a new LastPass session
vault = lastpass.Vault.open_remote('my_email@example.com', 'my_password')

# create a new secure note in LastPass
note = lastpass.SecureNote()
note.name = 'my_note'
note.set_field('username', 'my_username')
note.set_field('password', 'my_password')

# save the secure note to LastPass
vault.add(note)

# retrieve the secure note from LastPass
note = vault.get_note_by_name('my_note')
username = note.get_field('username')
password = note.get_field('password')

print(username, password)

Storing Credentials in KeePass

To use the KeePass Python library, you will need to install the pykeepass module:

pip install pykeepass

Here’s an example of how to store and retrieve credentials from KeePass:

from pykeepass import PyKeePass

# open KeePass database
kp = PyKeePass('my_database.kdbx', password='my_password')

# create new entry in KeePass database
new_entry = kp.add_entry(kp.find_groups(name='my_group')[0], 'my_entry')
new_entry.username = 'my_username'
new_entry.password = 'my_password'

# save changes to KeePass database
kp.save()

# retrieve entry from KeePass database
entry = kp.find_entries(title='my_entry')[0]
username = entry.username
password = entry.password

print(username, password)

Storing Credentials in System Environment Variables

Storing credentials in system environment variables is another secure way of storing passwords in Python applications. Environment variables are values that are set in the operating system’s environment and are accessible to any program running in that environment. This method is useful when you need to share credentials across multiple applications running on the same system.

Here’s an example of setting and accessing environment variables in Python:

import os

# set environment variable
os.environ['DB_USERNAME'] = 'my_username'
os.environ['DB_PASSWORD'] = 'my_password'

# access environment variable
db_username = os.environ.get('DB_USERNAME')
db_password = os.environ.get('DB_PASSWORD')

print(db_username, db_password)

Storing Credentials in a Virtual Environment

A virtual environment is a self-contained directory that contains all the necessary dependencies required by a Python application. Storing credentials in a virtual environment is a secure way of storing passwords because the credentials are only accessible by the application running in that environment.

Here’s an example of setting and accessing credentials in a virtual environment:

# create virtual environment
python -m venv my_venv

# activate virtual environment
source my_venv/bin/activate

# install dependencies
pip install requests

# set credentials as environment variables
export API_KEY='my_api_key'
export API_SECRET='my_api_secret'

# access credentials in Python code
import os

api_key = os.environ.get('API_KEY')
api_secret = os.environ.get('API_SECRET')

print(api_key, api_secret)

Conclusion

Using password managers like LastPass and KeePass Python libraries can help you securely store and manage passwords in Python applications. These libraries provide an easy-to-use interface to access the password manager’s functionality and integrate it with your Python code. It’s essential to ensure that the password manager is configured correctly and that only authorized users have access to the password manager’s credentials.

Storing credentials in system environment variables and virtual environments is a secure way of storing passwords in Python applications. However, it’s essential to ensure that the credentials are encrypted or hashed before storing them in environment variables or virtual environments. It’s also important to limit the access of environment variables and virtual environments to authorized users to prevent unauthorized access to sensitive information.

When dealing with security concerns, care must be taken throughout a project to ensure that credentials are not leaked or inadvertently exposed through the development process. For example, many developers have accidentally committed sensitive information like passwords and API keys to a project’s repository. CI/CD pipelines can be used to help ensure that sensitive data is not leaked. A simple git hook on the developer’s machine can be used to ensure sensitive data is not committed to the repository.

I have seen API keys and passwords placed in a project’s documentation. While you may say this should never happen (and it shouldn’t), people are lazy (especially programmers) and often pressed for time, and that can lead to mistakes, shortsightedness, and errors. Keeping project documentation in the project’s repository and running pre-commit hooks to ensure that sensitive passwords and API keys are not committed to the project’s repository can greatly reduce if not eliminate these types of errors and improve security.

Leave a Reply

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