Skip to main content

Improper dependency pinning

Need

Proper management of dependencies and version control

Context

  • Usage of Python 3.1 for developing Python applications
  • Usage of Django for building web applications in Python
  • Usage of requests for making HTTP requests in Node.js

Description

Non compliant code

# requirements.txt
Django>=3.1
requests>=2.24.0

The above code is a simplified representation of a requirements.txt file in a Python Django backend application. This file is used to manage Python dependencies for the application. The dependencies listed are Django and requests.

The vulnerability lies in the use of the >= operator. This operator means that the application will work with the specified version of the library or any later version. This is a problem because it does not explicitly pin the version of the dependencies that the application requires.

Because of this, when the application is deployed or built in a different environment (like another developer's machine, a staging environment, or a production server), the latest versions of the dependencies will be installed. These latest versions might include breaking changes, or they might have different security vulnerabilities compared to the versions that were used during development.

This can lead to inconsistent behavior across different environments, and it can also lead to security vulnerabilities if a newly introduced version of a dependency has a security vulnerability that wasn't present in the version that was used during development.

The application does not make explicit the whole dependency tree it requires (direct and indirect third-party libraries) and their respective version. This is known as Improper dependency pinning and can lead to serious security issues and application instability.

Steps

  • Identify all the dependencies your project needs, including indirect ones.
  • Specify the exact versions of the dependencies your project needs. Instead of using '>=', use '==' to pin to a specific version.
  • Update your 'requirements.txt' file with the exact versions of all dependencies.
  • Regularly update your dependencies to their latest stable versions to get the latest security patches and updates. After updating, thoroughly test your application to ensure it still works as expected with the new versions.
  • Consider using a tool like 'pip freeze' to generate a 'requirements.txt' file that includes the exact versions of all installed packages.
  • Consider using a dependency management tool that supports lock files, like pipenv or poetry. These tools automatically manage your project's dependencies and their versions for you.

Compliant code

# requirements.txt
Django==3.1.7
requests==2.24.0

The original code was vulnerable due to improper dependency pinning. It was using the 'greater than or equal to' (>=) operator to specify the versions of the dependencies. This could potentially lead to the installation of newer versions of the dependencies that may not be compatible with the application or may have security vulnerabilities.

The fixed code now uses the 'equal to' (==) operator to pin the dependencies to specific versions. This ensures that only the specified versions of the dependencies are installed. The versions chosen are the latest stable versions at the time of writing.

The dependencies pinned are:

  • Django: A high-level Python Web framework that encourages rapid development and clean, pragmatic design. Pinned to version 3.1.7.
  • requests: A simple, yet elegant HTTP library. Pinned to version 2.24.0.

It's important to regularly update these dependencies to their latest stable versions to get the latest security patches and updates. After updating, thoroughly test your application to ensure it still works as expected with the new versions.

Consider using a tool like 'pip freeze' to generate a 'requirements.txt' file that includes the exact versions of all installed packages. This can help ensure that your application's environment is reproducible, which is especially important for larger projects or when working in a team.

Also, consider using a dependency management tool that supports lock files, like pipenv or poetry. These tools automatically manage your project's dependencies and their versions for you, making it easier to maintain a secure and stable application.

References