Skip to content

Latest commit

 

History

History
117 lines (93 loc) · 10.2 KB

File metadata and controls

117 lines (93 loc) · 10.2 KB

Combining the provided vulnerability lists, we have identified a single vulnerability related to Arbitrary File Read in FileAwareMapping. Below is a consolidated description of this vulnerability, formatted as requested.

Arbitrary File Read via Environment Variable File Inclusion in FileAwareMapping

  • Description: The FileAwareMapping class in django-environ is vulnerable to arbitrary file read. This class is designed to handle environment variables, specifically to support reading values from files when an environment variable with a _FILE suffix is set. When an application using FileAwareMapping attempts to retrieve a configuration value (e.g., using env('CONFIG')), the class checks if an environment variable named CONFIG_FILE exists. If it does, the value of CONFIG_FILE is directly used as a file path, and the content of the file at that path is read and returned as the configuration value. Critically, no validation or sanitization is performed on this file path before attempting to open and read the file.

    An attacker who can control the environment variables of the application can exploit this behavior. By setting an environment variable with a _FILE suffix to a path pointing to a sensitive file on the server (e.g., /etc/passwd, sensitive configuration files, application code), the attacker can force the application to read the content of that file. When the application subsequently attempts to access the configuration value associated with the base name (e.g., CONFIG), FileAwareMapping will read and return the content of the attacker-specified file. If the application then exposes this file content (e.g., by logging it, displaying it in an error message, or using it in application logic that might leak the data), sensitive information can be disclosed to the attacker. This vulnerability is a form of path traversal because an attacker can potentially use relative paths (e.g., ../../../../etc/passwd) to access files outside the intended configuration directory, assuming the application's process has the necessary file system permissions.

  • Impact:

    • High - Information Disclosure. Successful exploitation of this vulnerability allows an external attacker to read arbitrary files from the server that the application process has access to. This can lead to the disclosure of sensitive data, including but not limited to:
      • Configuration files containing database credentials, API keys, or other secrets.
      • System files such as /etc/passwd which, while hashed, can still provide information or be targeted for offline cracking attempts.
      • Application source code, potentially revealing business logic, algorithms, or further vulnerabilities.

    The disclosure of such sensitive information can severely impact the confidentiality of the application and its data, potentially leading to further attacks such as privilege escalation, account compromise, or data breaches.

  • Vulnerability Rank: High

  • Currently Implemented Mitigations:

    • None. The current implementation within the FileAwareMapping.__getitem__ method directly uses the file path provided through the environment variable without any form of validation, sanitization, or restriction.
    • There are no checks in place to ensure that the file path is within an expected directory or to prevent path traversal attempts. The code directly opens and reads the file specified by the environment variable.
  • Missing Mitigations:

    • Path Sanitization and Validation: Implement robust path sanitization and validation within the FileAwareMapping.__getitem__ method before opening any file.
    • Base Directory Restriction: Enforce that the file path provided in the *_FILE environment variable must reside within a predefined, safe base directory.
    • Absolute Path Resolution and Prefix Checking: Utilize os.path.abspath to resolve the provided file path to its absolute form. Subsequently, verify if this absolute path starts with a safe, predefined base path. This prevents path traversal attempts using relative paths.
    • Restrictive File Access Permissions: Employ more restrictive file access permissions for the application process to limit the scope of readable files, thereby reducing the potential impact of successful path traversal exploitation.
    • Logging and Monitoring: Implement logging and monitoring mechanisms to detect and alert on suspicious file access attempts, particularly those involving paths outside of expected configuration directories or access to sensitive system files.
  • Preconditions:

    • Dependency on django-environ and FileAwareMapping: The application must be using the django-environ library, specifically utilizing the FileAwareMapping class or the higher-level FileAwareEnv which relies on it.
    • Environment Variable Control: An attacker must have the ability to influence or control the environment variables that are accessible to the running application and are processed by FileAwareMapping. This control could be achieved through various means, such as:
      • Misconfigurations in container orchestration systems (e.g., Kubernetes, Docker Compose).
      • Vulnerabilities in CI/CD pipelines allowing for environment variable injection during deployment.
      • Configuration injection vulnerabilities in multi-tenant environments or systems that dynamically set environment variables based on user input or external data.
  • Source Code Analysis: The vulnerability is located within the __getitem__ method of the FileAwareMapping class, found in the environ/fileaware_mapping.py file of the django-environ library.

    # File: environ/fileaware_mapping.py
    
    def __getitem__(self, key):
        if self.cache and key in self.files_cache:
            return self.files_cache[key]
        key_file = self.env.get(key + "_FILE") # [POINT-OF-INTEREST 1] - Retrieving file path from environment variable
        if key_file:
            with open(key_file, encoding='utf-8') as f: # [POINT-OF-INTEREST 2] - Directly opening file from attacker-controlled path
                value = f.read()
            if self.cache:
                self.files_cache[key] = value
            return value
        return self.env[key]
    1. [POINT-OF-INTEREST 1: key_file = self.env.get(key + "_FILE")]: This line retrieves the value of the environment variable formed by appending "_FILE" to the requested key (e.g., if key is "SECRET_KEY", it retrieves "SECRET_KEY_FILE"). The value obtained from the environment variable is directly assigned to the key_file variable. This is the point where an attacker-controlled value from the environment becomes the file path.

    2. [POINT-OF-INTEREST 2: with open(key_file, encoding='utf-8') as f:]: This line uses the open() function to open a file. Critically, the key_file variable, which is directly derived from the environment variable, is passed as the file path to the open() function without any prior validation or sanitization. This allows an attacker to specify any file path that the application process can access, leading to arbitrary file read.

    Visualization:

    graph LR
        A[Application Request: env("CONFIG")] --> B(FileAwareMapping.__getitem__);
        B --> C{Check CONFIG_FILE env var exists?};
        C -- Yes --> D[key_file = env("CONFIG_FILE")];
        D --> E{open(key_file)};
        E --> F{Read file content};
        F --> G[Return file content];
        C -- No --> H[Return env("CONFIG")];
    
    Loading

    The diagram illustrates the flow of execution. If the CONFIG_FILE environment variable is set (and controlled by the attacker), the application will directly attempt to open and read the file specified in this variable, leading to the vulnerability.

  • Security Test Case: To verify this vulnerability, the following steps can be performed in a test environment:

    1. Test Setup:

      • Create a test Django project using django-environ.
      • Modify your Django settings to initialize environ using FileAwareEnv instead of the default Env:
        # settings.py
        import environ
        env = environ.FileAwareEnv()
        TEST_CONFIG = env('TEST_CONFIG')
      • Create a simple Django view to display the value of TEST_CONFIG:
        # views.py
        from django.shortcuts import render
        from django.conf import settings
        
        def test_config_view(request):
            config_value = settings.TEST_CONFIG
            return render(request, 'test_config.html', {'config_value': config_value})
      • Create a basic template test_config.html to render config_value.
      • Ensure you have a sensitive file accessible to the application (e.g., /etc/passwd on a Linux system, or create a temporary file like /tmp/sensitive_test_file.txt with content "sensitive-test-data").
    2. Execution:

      • Start the Django development server.
      • Attacker Action: Before accessing the test view, set the environment variable TEST_CONFIG_FILE to point to the sensitive file you want to read. For example, in a terminal:
        export TEST_CONFIG_FILE="/etc/passwd" # Or "/tmp/sensitive_test_file.txt"
      • Attacker Action: Access the Django view in a web browser (e.g., http://127.0.0.1:8000/test_config_view/).
    3. Verification:

      • Observe the output in the browser. If the vulnerability is present, the content of the file specified in the TEST_CONFIG_FILE environment variable (e.g., /etc/passwd or /tmp/sensitive_test_file.txt) will be displayed in the web page.
      • To further confirm path traversal, try setting TEST_CONFIG_FILE to a path like /../../../../etc/passwd and verify if you can still read the file.
    4. Conclusion:

      • If the content of the sensitive file is displayed in the web page, it confirms the Arbitrary File Read vulnerability. This demonstrates that an attacker who can control environment variables can successfully read arbitrary files on the server using the FileAwareMapping functionality.

By addressing the missing mitigations, particularly by implementing path validation and restrictions, the risk of this arbitrary file read vulnerability and the potential for sensitive data disclosure can be effectively eliminated.