Skip to main content

Business information leak - Credentials

Need

Protection of business credentials from unauthorized access and leakage

Context

  • Usage of Python 3 for developing applications and scripts
  • Usage of Django for building web applications

Description

Non compliant code

from django.contrib.auth.models import User

def leak_credentials():
users = User.objects.all()
for user in users:
print("Username: ", user.username)
print("Password: ", user.password)

The above code is a Django function that retrieves all users from the database and prints their usernames and passwords. This code is vulnerable to information leakage as it exposes sensitive user data.

In the Django framework, the user model is used to store user-related data. The function User.objects.all() retrieves all user objects from the database. The for loop then iterates over each user object, printing the username and password.

The print statements are the main source of vulnerability here. They output the username and password of each user, which is a severe security risk. If an attacker gains access to the console logs or if this output is logged somewhere within the system, they can easily obtain the credentials for all users.

This could lead to unauthorized access to user accounts, data breaches, and potentially severe damage to the business, including loss of sensitive data, financial loss, and damage to reputation.

It's also worth noting that in a secure system, passwords should never be stored in plaintext as they are here. Django provides built-in tools for hashing and salting passwords to prevent them from being exposed even if a data breach occurs.

Steps

  • Remove the code that prints out the user's password. Passwords should never be displayed or logged.
  • Ensure that passwords are stored securely. Django's User model already hashes passwords, so you should never need to access the raw password value.
  • Implement proper logging and error handling. Instead of printing out user information, log relevant events and handle errors in a way that doesn't expose sensitive information.
  • Consider using Django's built-in views and forms for user management. These are designed to handle sensitive data securely.
  • Regularly review and update your security practices. This includes keeping your software up to date, using secure coding practices, and regularly auditing your code for security vulnerabilities.

Compliant code

from django.contrib.auth.models import User
import logging

logger = logging.getLogger(__name__)

def handle_users():
users = User.objects.all()
for user in users:
logger.info("Username: %s", user.username)

The updated code removes the vulnerability of leaking user credentials. The function handle_users now only logs the username of each user, and does not print or log any password information.

The logger.info method is used to log the username of each user. This is a secure way to handle user information, as it does not expose sensitive data. The logger is set up with getLogger(__name__), which sets the logger's name to the name of the current module. This is a common practice that helps with tracking where logged events are coming from.

The password information is completely removed from the function. In Django, the User model automatically hashes passwords, so there is never a need to access the raw password value. By not including the password in the log, we eliminate the risk of password leaks.

In addition to these changes, it's recommended to use Django's built-in views and forms for user management, as they are designed to handle sensitive data securely. Regular reviews and updates of security practices, including keeping software up to date, using secure coding practices, and regularly auditing code for security vulnerabilities, are also crucial for maintaining secure applications.

References