You just cloned a fresh source code repository and want to get a quick sense of its dependencies. Our tool, it-depends, can get you there.
We are proud to announce the release of it-depends, an open-source tool for automatic enumeration of dependencies. You simply point it to a source code repository, and it will build a graph with the required dependencies. it-depends currently supports cargo, npm, pip, go, CMake, and autotools codebases, packages in their associated package managers, and Ubuntu apt.
Modern programming languages and packaging frameworks increasingly include utilities to enumerate dependencies and even map them to known vulnerabilities (e.g., npm audit, cargo audit, and pip-audit). it-depends unifies these functionalities into one tool that supports languages and frameworks for which no similar tool exists, such as autotools and CMake. Simply run it-depends
in the root of a source code repository, and the tool will produce a software bill of materials (SBOM) for all of the packages on which the repository could depend. it-depends not only detects known-vulnerable dependencies, but it also identifies duplicate functionality within a repository, which can support software debloating efforts. “Why is this repository using both libsodium and libssl?”
it-depends uses the CVEdb and Google’s Open Source Vulnerabilities (OSV) databases to determine which known vulnerabilities may be reachable from any package. After finding matching entries, the tool produces a comprehensive list of all reachable CVEs in a code repository or package.
Existing approaches typically resolve only direct dependencies or rely on a package lock file. In contrast, it-depends recursively builds a project’s dependency graph starting from either a source code repository or a package specification, enumerating the superset of all feasible dependency resolutions, not just a single resolution. This can help identify latent upstream vulnerabilities that might exist only in a subset of the universe of all feasible dependency resolutions.
Existing solutions stop within the walled garden of their package management ecosystem. it-depends, in contrast, is able to detect native library usage and interdependency. For example, it-depends correctly identifies that the Python package pytz depends on the native library libtinfo6, which itself depends on libcrypt1, which depends on libc6, … and so on.
Why enumerating dependencies is hard
- Semantic versioning: We don’t care only about the specific versions installed on a system; we want to reason about all possible versions that can satisfy the dependencies.
- Some build systems such as autotools and CMake do not have a concept of packages, and native library versioning is not well defined.
- What if a package written in a high-level language, like Python or JavaScript, uses native libraries?
- Mapping CVEs to source code packages is nontrivial.
Basic functionality (business as usual)
it-depends is written in Python and is easy to extend. It is built on a set of pluggable resolvers to handle different package managers and source code repositories. Each resolver acts as an oracle for its specific universe of packages, expanding the global dependency graph. Adding a resolver for a new build system or package manager basically requires only that one resolve method be implemented:
from it_depends.dependencies import DependencyResolver, Dependency, Package class CustomResolver(DependencyResolver): def resolve(self, dependency: Dependency) -> Iterator[Package]: """Yields all packages that satisfy the given dependency""" raise NotImplementedError("TODO: Implement")
Native resolution (the not-so-secret sauce)
it-depends features a generic plug-in to infer native operating system-level dependencies of a given package. To accomplish this, each package is installed in a container, and the native libraries are monitored using ptrace. File accesses are translated to the Ubuntu packages that provide the library file loaded by the package, and inter-native dependencies are extracted from the Ubuntu package repository. A baseline is established to remove packages that are inherent to the type of package currently being analyzed.
Try it yourself!
it-depends is free and open source. You can install it by running pip3 install it-depends. Further installation instructions are available on the tool’s GitHub page. Please try it, and let us know how it works!
Acknowledgements
it-depends was developed by Trail of Bits based upon work supported by DARPA under Contract No. HR001120C0084 (Distribution Statement A, Approved for Public Release: Distribution Unlimited). Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the United States Government or DARPA.