Skip to main content

Non-encrypted confidential information - LDAP

Need

Secure storage and transmission of LDAP service credentials

Context

  • Usage of Python 3 for developing applications and scripts
  • Usage of LDAP for directory services and user authentication

Description

Non compliant code

import ldap

# LDAP settings
ldap_server = "ldap://my-ldap-server.com"
ldap_username = "admin"
ldap_password = "password"

# initialize
l = ldap.initialize(ldap_server)
l.simple_bind_s(ldap_username, ldap_password)

In the above Python code, we are using the python-ldap library to connect to an LDAP server. The LDAP server URL, username, and password are stored as plain text strings in the code.

The ldap.initialize function is used to set up a connection to the specified LDAP server, and the simple_bind_s function is used to bind or log in to the LDAP server using the specified username and password.

The vulnerability here is that the LDAP service credentials are exposed in plain text in the code. This means that anyone who can view the code can see these credentials. This is a significant security risk as these credentials can be used to gain unauthorized access to the LDAP server. Additionally, if these credentials are used elsewhere, those systems are also at risk.

It is generally a bad practice to store sensitive information such as passwords, API keys, or similar credentials in the source code. Instead, such sensitive information should be stored in a secure manner, such as environment variables or secure vaults, and accessed via secure methods.

Steps

  • Remove the hard-coded LDAP credentials from the code.
  • Store the LDAP credentials in a secure configuration file or a secure environment variable.
  • Encrypt the configuration file or environment variable where the LDAP credentials are stored.
  • Modify the code to retrieve the LDAP credentials from the secure configuration file or environment variable.
  • Ensure that the code decrypts the LDAP credentials before using them.

Compliant code

import ldap
import os
from cryptography.fernet import Fernet

# LDAP settings
ldap_server = "ldap://my-ldap-server.com"

# Retrieve encrypted LDAP credentials from environment variables
ldap_username_encrypted = os.getenv('LDAP_USERNAME')
ldap_password_encrypted = os.getenv('LDAP_PASSWORD')

# Retrieve the key to decrypt the credentials
key = os.getenv('LDAP_KEY')

# Create a cipher suite
cipher_suite = Fernet(key)

# Decrypt the credentials
ldap_username = cipher_suite.decrypt(ldap_username_encrypted).decode()
ldap_password = cipher_suite.decrypt(ldap_password_encrypted).decode()

# initialize
l = ldap.initialize(ldap_server)
l.simple_bind_s(ldap_username, ldap_password)

The updated code no longer contains hard-coded LDAP credentials. Instead, it retrieves the encrypted credentials from environment variables.

The encryption key is also stored as an environment variable. This key is used to create a cipher suite with the Fernet symmetric encryption library.

The cipher suite is then used to decrypt the LDAP credentials. The decrypted credentials are used to initialize and bind to the LDAP server.

This approach ensures that the LDAP credentials are not exposed in the code. It also provides the added security of encrypting the credentials.

Remember to securely set your environment variables for 'LDAP_USERNAME', 'LDAP_PASSWORD', and 'LDAP_KEY' in your production environment.

The 'LDAP_USERNAME' and 'LDAP_PASSWORD' should be encrypted using the 'LDAP_KEY'. You can use the Fernet library to encrypt the credentials before setting the environment variables.

This approach significantly reduces the risk of exposing LDAP credentials in your code.

References