Learning Center
Transitive Dependencies
What are transitive dependencies?
Transitive dependencies are indirect dependencies that a software project inherits from its direct dependencies. In other words, when a package (A) depends on another package (B), and package B, in turn, depends on package C, package C is a transitive dependency of package A.
For example:
- Your project depends on Library A (direct dependency)
- Library A depends on Library B (transitive dependency)
- Library B depends on Library C (another transitive dependency)
While you may explicitly include on Library A in your project, you are also pulling in Library B and Library C, often without director control or visibility over them.
Transitive dependencies are an unavoidable part of modern software development, and they introduce hidden security risks. Organizations need to actively map, monitor, and manage these dependencies to reduce vulnerabilities and enhance software security.
Why are transitive dependencies uniquely challenging?
Transitive dependencies are especially difficult to manage because the scale continues to grow, many tools do not provide the visibility needed and updating them is not something you can control.
Scale
It's not uncommon for a modern application to contain thousands of transitive dependencies. In speaking with customers, we often learn that security teams are only scanning for direct dependencies - this is often a single digit percentage of the attack surface.
Visibility
Most traditional tools only show direct dependencies or display flat lists that hide the crucial relationships between components. This creates dangerous blind spots:
- Which of your applications use a vulnerable component?
- Through which path does that component enter your application?
- Is the vulnerable code actually reachable in your specific implementation?
Without these insights, teams waste resources fixing theoretical issues while missing exposure.
Updates
When a vulnerability is discovered in a transitive dependency, updating isn't always straightforward. You typically can't update the transitive dependency directly - you need to update the direct dependency that pulls it in.
But what if:
- Multiple direct dependencies pull in different versions of the same component?
- The direct dependency hasn't been updated to use the fixed version?
- Updating the direct dependency breaks compatibility with other components?
These scenarios create "dependency hell" situations that can paralyze development teams.
How many transitive dependencies does a typical application contain?
Most enterprise applications contain hundreds to thousands of transitive dependencies. We've seen applications with as few as 200 and as many as 20,000+ dependencies, with transitive dependencies typically accounting for more than 90% of that total.
Can we just avoid using dependencies with complex dependency trees?
While minimizing dependencies is generally good practice, completely avoiding transitive dependencies isn't feasible in modern development. The efficiency gains from using established libraries far outweigh the alternative of writing everything from scratch. The key is managing these dependencies effectively rather than trying to eliminate them.
How do transitive dependencies affect application performance?
Beyond security implications, excessive or duplicated dependencies can impact application size, startup time, and runtime performance. Proper dependency management helps identify opportunities to optimize your dependency tree, potentially improving application performance.
How often should we audit our transitive dependencies?
Vulnerability databases update constantly, with dozens of new CVEs published daily. Rather than periodic audits, we recommend continuous monitoring that alerts you when new vulnerabilities affect your specific dependency graph. This approach ensures you're aware of new risks as soon as they're discovered.
What's the most effective way to remediate vulnerable transitive dependencies?
The optimal remediation strategy depends on your specific dependency graph. Options include:
- Updating the direct dependency that pulls in the vulnerable component
- Replacing the direct dependency with an alternative that doesn't use the vulnerable component
- Adding dependency constraints to force use of a safe version
- In some cases, forking and fixing the vulnerable dependency
Kusari can help identify the most efficient remediation path based on your specific dependency structure.