Insecure temporary files - Python

Insecure temporary files - Python

Need

Secure handling of temporary files

Context

  • Usage of Python 3 for developing applications and scripts
  • Usage of os for accessing operating system-related information
  • Usage of tempfile for creating temporary files and directories

Description

Non compliant code

        import os
import tempfile

def sensitive_data():
    temp = tempfile.NamedTemporaryFile(delete=False)
    temp.write(b'Sensitive Information')
    temp.close()
    print("Temporary file path: ", temp.name)
    return temp.name

def deploy_temp_file():
    temp_file_path = sensitive_data()
    # This is where the deployment to production happens
    with open(temp_file_path, 'r') as file:
        print("Deploying file to production: ", file.read())
    os.unlink(temp_file_path)

deploy_temp_file()
        
        

In the above code, we are creating a temporary file using Python's tempfile module and writing sensitive information to it. This temporary file is then being deployed to a production environment.

The function sensitive_data creates a temporary file, writes some sensitive information to it, and then closes the file. The path to the temporary file is then returned.

The function deploy_temp_file calls the sensitive_data function to get the path to the temporary file. It then opens the file, reads the sensitive information, and deploys it to a production environment. After this, the temporary file is deleted.

This code is vulnerable because sensitive information is being written to a temporary file, which can be accessed by other processes or users on the same system before it is deleted. Moreover, if the process is interrupted before the file is deleted (for example, if the Python script crashes), the temporary file with sensitive information will be left on the system. This can lead to information disclosure and potential security risks.

Steps

  • Use secure methods to create temporary files. Python's tempfile module provides the NamedTemporaryFile function with a delete parameter. When set to True, the file is deleted as soon as it is closed.
  • Encrypt sensitive data before writing it to a temporary file. This way, even if an attacker gains access to the file, they won't be able to understand the information without the encryption key.
  • Avoid storing sensitive information in temporary files whenever possible. If you must use a temporary file, make sure to securely delete it as soon as you're done using it.
  • Ensure that the permissions for the temporary file are set to be as restrictive as possible. Only the user who needs to use the file should have read/write access.
  • Do not deploy sensitive temporary files to the production environment. If you need to use a temporary file in production, create it directly in the production environment and delete it as soon as you're done using it.

Compliant code

        import os
import tempfile
from cryptography.fernet import Fernet

def sensitive_data():
    # Generate a key for encryption
    key = Fernet.generate_key()
    cipher_suite = Fernet(key)

    # Encrypt sensitive data
    data = b'Sensitive Information'
    cipher_text = cipher_suite.encrypt(data)

    # Create a secure temporary file
    temp = tempfile.NamedTemporaryFile(delete=True)
    temp.write(cipher_text)
    temp.close()
    print("Temporary file path: ", temp.name)
    return temp.name, key

def deploy_temp_file():
    temp_file_path, key = sensitive_data()
    cipher_suite = Fernet(key)

    # This is where the deployment to production happens
    # The file is read, decrypted and then deleted securely
    with open(temp_file_path, 'rb') as file:
        encrypted_data = file.read()
        plain_text = cipher_suite.decrypt(encrypted_data)
        print("Deploying file to production: ", plain_text)
    os.unlink(temp_file_path)

deploy_temp_file()
        
        

The updated code now includes encryption for sensitive data using the cryptography library's Fernet module. A key is generated for the encryption and the sensitive data is encrypted before being written to the temporary file. This ensures that even if an attacker gains access to the file, they won't be able to understand the information without the encryption key.

The tempfile.NamedTemporaryFile function is used with the delete parameter set to True. This means that the file is deleted as soon as it is closed, reducing the window of opportunity for an attacker to access the file.

In the deploy_temp_file function, the temporary file is opened in binary mode for reading. The encrypted data is read from the file, decrypted using the previously generated key, and then the file is securely deleted using os.unlink.

This code avoids deploying sensitive temporary files to the production environment. If a temporary file is needed in production, it should be created directly in the production environment and deleted as soon as it is no longer needed.

References