Tool Reviews

Endor Labs SCA Review: Reachability Analysis Changes the Game

A review of Endor Labs and its reachability-based approach to software composition analysis, examining how call graph analysis reduces vulnerability noise.

Nayan Dey
DevSecOps Engineer
6 min read

The biggest problem with traditional SCA tools is noise. They tell you a dependency has a vulnerability, but they do not tell you whether your code actually uses the vulnerable function. Endor Labs was founded specifically to solve this problem through reachability analysis, and their approach deserves serious attention.

The Noise Problem

A typical enterprise application has hundreds of direct dependencies and thousands of transitive dependencies. A traditional SCA scanner reports vulnerabilities in all of them. The result is hundreds or thousands of findings, most of which are not exploitable because the application never calls the vulnerable code path.

Development teams facing this wall of findings do one of two things: they ignore the tool entirely, or they spend weeks triaging findings that turn out to be irrelevant. Neither outcome improves security. The signal-to-noise ratio of traditional SCA is the primary reason adoption stalls in many organizations.

Reachability Analysis

Endor Labs builds call graphs of your application code and maps them against the dependency tree. When a vulnerability is found in a dependency, Endor Labs checks whether your application actually reaches the vulnerable function through its call chain.

A practical example: your application depends on library A, which depends on library B, which has a vulnerable function parseXML(). Traditional SCA flags this as a vulnerability. Endor Labs checks whether your code (directly or transitively through library A) ever calls parseXML(). If it does not, the vulnerability is marked as unreachable and deprioritized.

In Endor Labs' published benchmarks, reachability analysis typically reduces actionable findings by 70-80%. In our testing, the reduction was closer to 60% for Java applications and 50% for JavaScript. The variance depends on the codebase structure and how many dependencies are used comprehensively versus sparingly.

How the Call Graph Works

Endor Labs performs static analysis on your source code to build a call graph. This call graph maps function calls from your code into dependency code, through the entire transitive dependency chain. The analysis is language-specific and leverages the type system, import structure, and call patterns of each supported language.

The call graph construction is computationally expensive. Initial analysis of a large Java monorepo can take 15-30 minutes. Subsequent incremental analyses on changed code are much faster, typically a few minutes. This is slower than a simple dependency scan but the reduction in false positives justifies the investment.

The accuracy of the call graph depends on the language. Java and Go, with their explicit type systems and static dispatch, produce the most reliable call graphs. JavaScript and Python, with dynamic dispatch and runtime code loading, present challenges. Endor Labs handles common dynamic patterns but acknowledges that some call paths may be missed in highly dynamic codebases.

Dependency Risk Scoring

Beyond reachability, Endor Labs assigns risk scores to dependencies based on project health indicators: maintenance activity, contributor diversity, security practices, release frequency, and dependency depth. This is similar to OpenSSF Scorecard but integrated directly into the SCA workflow.

The dependency risk score helps answer a question that vulnerability counts miss: "Is this dependency well-maintained enough that vulnerabilities will be patched promptly?" A dependency with zero known vulnerabilities but one maintainer who hasn't committed in six months is arguably riskier than a dependency with a patched CVE and an active maintenance team.

Language Support

Endor Labs supports Java, JavaScript/TypeScript, Python, Go, Rust, Kotlin, and Scala for full reachability analysis. C/C++ and Ruby have basic SCA support without reachability. The Java support is the most mature, which is not surprising given the language's amenability to static analysis.

For organizations with polyglot codebases, the uneven reachability support means you get different quality of results depending on the language. Java services get precise, low-noise results. Python services get traditional SCA with the dependency risk overlay.

CI/CD Integration

Endor Labs provides a GitHub App, CLI tool, and GitHub Action for CI integration. The PR experience is well-designed: findings appear as inline comments with reachability context, and the overall risk assessment is summarized in the check status.

The CLI can also be used in GitLab CI, Jenkins, and other CI platforms. Setup is straightforward, though the initial call graph construction adds noticeable time to CI runs.

Endor Labs also supports a "station" deployment model where analysis runs on your infrastructure rather than sending code to their cloud. This matters for organizations with strict code residency requirements.

Policy Engine

The policy engine lets you define rules based on vulnerability severity, reachability status, dependency health scores, and license types. You can create policies like "block merges if there are any reachable critical vulnerabilities" or "warn on dependencies with a health score below 30."

The combination of reachability data and health scores in policy decisions is more nuanced than what most SCA tools offer. You can be strict about vulnerabilities that are actually reachable while being more lenient about unreachable findings in healthy dependencies.

Pricing

Endor Labs is venture-funded and positioned as an enterprise product. Pricing is not publicly listed but is based on the number of repositories and developers. Early reports suggest pricing competitive with Snyk for similar deployment sizes.

A free tier exists for open source projects, which is consistent with the market expectation for SCA tools.

Limitations

The call graph analysis has blind spots. Reflection, runtime code generation, dynamic imports, and plugin architectures can create call paths that static analysis misses. Endor Labs documents these limitations and errs on the side of marking potentially reachable findings as reachable rather than dismissing them.

The tool is relatively young. The rule library and ecosystem coverage are growing but not yet at the level of mature tools like Snyk or Sonatype. Integration options outside GitHub are more limited than competitors.

Reachability analysis is also a point-in-time assessment. Your code might not reach a vulnerable function today, but a refactor next week could change that. Continuous scanning catches this, but the risk of false confidence exists if teams treat "unreachable" as "permanently safe."

How Safeguard.sh Helps

Safeguard.sh integrates with Endor Labs to leverage reachability data within a broader supply chain security context. While Endor Labs focuses on whether vulnerabilities are reachable in your code, Safeguard.sh tracks the full lifecycle of those dependencies across your organization: which teams use them, which versions are deployed, and how they relate to your SBOM commitments. Safeguard.sh turns Endor Labs' precise reachability findings into organizational action by mapping them across your entire software portfolio.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.