ISMS

Dependency Scanning: Finding Vulnerabilities in Third-Party Libraries

TL;DR
  • Modern applications consist of 80-90% third-party libraries. A single vulnerable library can compromise the entire application (Log4Shell, Spring4Shell).
  • Dependency scanning automatically searches all direct and transitive dependencies for known vulnerabilities (CVEs) and creates a Software Bill of Materials (SBOM).
  • The most important tools are Dependabot (GitHub-native), Renovate (flexible, multi-platform), Snyk (commercial, with prioritization), and Trivy (open source, multi-scanner).
  • Not every vulnerability found needs to be fixed immediately. Prioritize by CVSS score, reachability of the vulnerability in your code, and availability of a fix.
  • An SBOM (Software Bill of Materials) documents all software components and their versions. NIS2 and various industry standards increasingly require SBOMs.

The Risk in Your Dependencies

When you build a modern web application, you write only a fraction of the code yourself. The rest comes from third-party libraries: frameworks, utility libraries, ORM tools, HTTP clients, logging libraries, cryptography modules, and hundreds of other packages.

A typical Node.js project with Express and some common libraries easily has 500 to 1,000 dependencies (including transitive dependencies — dependencies of dependencies). A Java project with Spring Boot brings similarly many. Each of these libraries can contain vulnerabilities, and you are responsible for identifying and fixing them.

Prominent Examples

Log4Shell (CVE-2021-44228): A critical vulnerability in the Java logging library Log4j that enabled remote code execution. Nearly every Java application was potentially affected because Log4j was embedded as a transitive dependency in thousands of other libraries. Many organizations did not even know they were using Log4j.

Spring4Shell (CVE-2022-22965): A remote code execution vulnerability in Spring Framework. Less critical than Log4Shell, but with similarly broad impact on Java-based web applications.

event-stream (2018): An npm package used by millions of projects was taken over by a new maintainer who injected malicious code. A typical supply chain attack. The code stole cryptocurrency wallets. No CVE, no known bug, but a supply chain attack through the dependency chain.

ua-parser-js (2021): Another popular npm package (7 million downloads per week) where compromised versions were published containing cryptominers and password stealers.

These examples illustrate two different risks: known vulnerabilities in legitimate software (Log4Shell, Spring4Shell) and supply chain attacks where malicious code is injected into trusted packages (event-stream, ua-parser-js).

What Dependency Scanning Is

Dependency scanning is the automated process of identifying all your software's dependencies (direct and transitive) and comparing them against databases of known vulnerabilities.

The Process

1. Identify dependencies: The tool reads your project's dependency definitions (package.json and package-lock.json for Node.js, pom.xml or build.gradle for Java, composer.json and composer.lock for PHP, requirements.txt or poetry.lock for Python, go.sum for Go) and creates a complete dependency tree, including all transitive dependencies.

2. Match vulnerabilities: The identified dependencies and their versions are compared against vulnerability databases. The most important databases are NVD (National Vulnerability Database) from NIST, which is the official US vulnerability database with CVE entries (Common Vulnerabilities and Exposures), GitHub Advisory Database, a community-maintained database with language-specific vulnerabilities, and OSV (Open Source Vulnerability Database) from Google, which provides an aggregated format combining multiple databases.

3. Assess results: For each vulnerability found, the tool provides the CVE identifier, the CVSS score (severity from 0 to 10), a description of the vulnerability, the affected version, and the first fixed version (if available).

4. Remediate: Update the affected library to a version that fixes the vulnerability. If no fix is available: assess the risk and, if necessary, implement a workaround or replace the library.

Tools Compared

Dependabot (GitHub)

Dependabot is integrated into GitHub and detects vulnerabilities in your repositories' dependencies. It automatically creates pull requests with updates for vulnerable libraries.

Strengths: Free for all GitHub repositories (public and private), no installation or configuration needed (simply enable), automatic pull requests with changelog and compatibility notes, supports all common package managers (npm, pip, Maven, Gradle, Composer, Bundler, Go Modules, Cargo, and more), security alerts with CVSS score and patch recommendation.

Weaknesses: Only available on GitHub (not for GitLab, Bitbucket, or self-hosted Git servers), limited configurability for complex mono-repos, no reachability analysis (does not show whether the vulnerable function is actually called in your code), no support for container image scanning.

Suitable for: Teams using GitHub that are looking for an uncomplicated, free solution.

Renovate

Renovate is an open-source tool for automated dependency updates. It is more flexible than Dependabot and supports more platforms.

Strengths: Supports GitHub, GitLab, Bitbucket, Azure DevOps, and self-hosted Git servers, highly configurable (automerge for patch updates, grouping of updates, custom schedules), support for lock file maintenance, detects and updates Docker image tags, Terraform modules, and Helm chart versions, Mend.io (formerly WhiteSource) offers a hosted SaaS version.

Weaknesses: Higher initial configuration effort than Dependabot, vulnerability detection is less prominent than update management (Renovate is primarily an update tool, not a security scanner).

Suitable for: Teams with complex setups (mono-repos, multi-platform) or those not on GitHub.

Snyk

Snyk is a commercial security tool that combines dependency scanning, container scanning, SAST, and infrastructure-as-code scanning.

Strengths: Reachability analysis (shows whether the vulnerable function is actually called in your code path, which significantly improves prioritization), fix recommendations with minimal version change (not always the latest major update, but the smallest change that fixes the vulnerability), CLI integration for local scans, IDE plugins (VSCode, IntelliJ), extensive database with proprietary vulnerability data (in addition to NVD), container image scanning.

Weaknesses: The free version is limited to 200 tests per month, the advanced features (reachability analysis, custom policies) are paid, vendor lock-in (proprietary database and prioritization engine).

Cost: Free tier for open-source projects and small teams. Team plan starting at approximately $52 per month per developer.

Suitable for: Teams looking for a comprehensive security platform with good prioritization and willing to pay for it.

Trivy

Trivy is an open-source security scanner from Aqua Security that finds vulnerabilities in container images, filesystems, Git repositories, and Kubernetes clusters.

Strengths: Open source and free, scans dependencies, container images, and infrastructure-as-code with a single tool, fast and lightweight, good CI/CD integration (GitHub Actions, GitLab CI), supports SBOM generation in SPDX and CycloneDX formats.

Weaknesses: Less sophisticated prioritization than Snyk (no reachability analysis), no automatic pull requests (pure scanner, not an update tool), less IDE integration.

Suitable for: Teams looking for a versatile open-source tool for container and dependency scanning.

OWASP Dependency-Check

OWASP Dependency-Check is an open-source tool specifically designed to detect vulnerabilities in project dependencies.

Strengths: Open source and free, good support for Java/Maven and .NET/NuGet, detailed HTML reports, Jenkins plugin available.

Weaknesses: Higher false positive rate than commercial tools, slower scans (downloads the NVD database with each scan if not cached), less good support for Node.js and Python compared to Snyk or Trivy.

Suitable for: Java and .NET teams looking for a free, established tool.

Integrating Dependency Scanning into the CI/CD Pipeline

The most effective use of dependency scanning is integration into the CI/CD pipeline as part of the Secure Development Lifecycle. Every commit or pull request is automatically scanned, and the build is aborted when critical vulnerabilities are found.

Implementation Strategy

Phase 1: Create visibility (Week 1). Enable dependency scanning for all repositories. On GitHub: enable Dependabot (one click). On GitLab: enable GitLab Dependency Scanning. On other platforms: integrate Trivy or Snyk into the pipeline. Goal: you know which vulnerabilities exist in your projects.

Phase 2: Prioritize (Weeks 2-3). Assess the vulnerabilities found. Not every vulnerability requires immediate action. Prioritize by CVSS score (9.0-10.0: fix immediately, 7.0-8.9: within one week, 4.0-6.9: within one month, below 4.0: in the next regular update cycle), by reachability (is the vulnerable function actually called in your code?), and by availability of a fix (is there a fixed version?).

Phase 3: Introduce a quality gate (Weeks 3-4). Define a policy: "No merge to the main branch if critical or high vulnerabilities are present." Configure the pipeline to fail on critical findings. Allow exceptions for vulnerabilities that cannot be remediated (no fix available), but document the exceptions and review them regularly.

Phase 4: Expand automation (ongoing). Enable automerge for patch updates (e.g., 1.2.3 to 1.2.4) suggested by Dependabot or Renovate, provided all tests pass. This keeps your dependencies up to date without manual effort.

SBOM: Software Bill of Materials

An SBOM is a machine-readable inventory of all software components contained in an application, including libraries, frameworks, plugins, and their versions and licenses.

Why SBOMs Are Becoming Important

The US government made SBOMs mandatory for software delivered to federal agencies with Executive Order 14028 (2021). The EU follows with the Cyber Resilience Act (CRA), which requires SBOMs for products with digital elements. NIS2 requires supply chain security, and SBOMs are an essential instrument for that.

Even without regulatory obligation, SBOMs are useful: when a new vulnerability like Log4Shell becomes known, you can determine within minutes which of your applications are affected using an SBOM. Without an SBOM, you must search each repository individually.

SBOM Formats

The two established formats are SPDX (Software Package Data Exchange), developed by the Linux Foundation, an ISO standard (ISO/IEC 5962:2021) focused on license compliance and software composition, and CycloneDX, developed by OWASP, focused on security and vulnerability tracking, also supporting hardware and service components.

Both formats are available in JSON and XML and are supported by the common tools.

Generating SBOMs

Syft (by Anchore, open source) generates SBOMs from filesystems, container images, and archives. Supports SPDX and CycloneDX. Example: syft dir:. -o cyclonedx-json > sbom.json.

Trivy can generate SBOMs in addition to vulnerability scans: trivy fs --format cyclonedx -o sbom.json ..

CycloneDX plugins are available for Maven (cyclonedx-maven-plugin), npm (@cyclonedx/cyclonedx-npm), Python (cyclonedx-bom), and other ecosystems.

Generate the SBOM in the CI/CD pipeline with every build and archive it. This gives you a complete component list for every version of your software.

Transitive Dependencies: The Invisible Risk

The biggest challenge in dependency scanning is transitive dependencies: libraries you do not directly include but that are delivered as dependencies of your dependencies.

You use Library A, which depends on Library B, which depends on Library C. If Library C has a vulnerability, you are affected even though you never consciously included Library C and may not even know about it.

Handling Transitive Vulnerabilities

Use lock files: Lock files (package-lock.json, composer.lock, poetry.lock, go.sum) pin the exact versions of all dependencies, including transitive ones. Without a lock file, each build can download different versions.

Override transitive dependencies: Most package managers allow you to explicitly pin transitive dependencies to a specific version. In npm: overrides in package.json. In Maven: dependencyManagement. In Gradle: resolutionStrategy. Use this to force vulnerable transitive dependencies to a fixed version, even if the direct dependency has not yet updated them.

Regularly prune the dependency tree: Remove direct dependencies that are no longer needed. Each removed direct dependency also eliminates its transitive dependencies. Regularly check whether leaner alternatives exist: do you really need Lodash, or do native JavaScript methods suffice?

False Positives and Prioritization

Dependency scanning tools produce false positives: vulnerabilities that are not exploitable in your specific context. A vulnerability in a function you never call is theoretically a risk (the code is present), but practically less urgent than a vulnerability in a function executed with every request.

Handling False Positives

Use reachability analysis: Snyk and some other tools offer a reachability analysis that checks whether the vulnerable function lies in your code path. This significantly reduces the number of relevant findings.

Document exceptions: If you classify a vulnerability as not relevant (e.g., because the vulnerable function is not reachable in your context), document this decision. Tools like Snyk and Trivy support ignore files with justifications and expiration dates.

Review regularly: Exceptions should have an expiration date (e.g., 90 days). After that, the vulnerability is reassessed: is there a fix available now? Has the code changed?

Dependency Scanning and Regulatory Requirements

NIS2

NIS2 Article 21 Paragraph 2 Letter e requires "security measures in the acquisition, development, and maintenance of network and information systems, including vulnerability management and disclosure." Dependency scanning is a direct contribution to vulnerability management. Paragraph 2 Letter d requires "supply chain security." SBOMs and dependency scanning address the software supply chain component.

ISO 27001

Annex A, Control A.8.9 (Configuration management), requires the management of the configuration of hardware, software, and services. An SBOM is part of software configuration documentation. Control A.8.8 (Management of technical vulnerabilities) requires that technical vulnerabilities are identified and remediated promptly. Building a vulnerability management process is the organizational foundation for this. Dependency scanning is the tool for it.

Cyber Resilience Act (CRA)

The CRA requires an SBOM and documented vulnerability management for products with digital elements. Dependency scanning and SBOM generation in the CI/CD pipeline are the technical implementation.

From Tool to Process

Dependency scanning is not a one-time project but a continuous process. Scans run with every commit and additionally on a regular schedule (daily or weekly) against the main branch. New vulnerabilities are assessed and prioritized. Critical vulnerabilities are remediated within defined timeframes. Exceptions are documented and regularly reviewed. SBOMs are generated and archived with every release. The process is documented within the ISMS and demonstrated during audits.

Once you have established this process, you are well protected against the most common software supply chain risks and simultaneously meet essential requirements of NIS2, ISO 27001, and the Cyber Resilience Act. In ISMS Lite, your dependency scanning process with vulnerability assessments, SLAs, and exceptions can be documented and prepared for audits.

Common Mistakes in Dependency Scanning

Only checking direct dependencies. Many teams only update the libraries they directly include and forget about transitive dependencies. Log4Shell showed that the vulnerable library is often several levels deep in the dependency chain. Use tools that analyze the entire dependency tree.

Ignoring findings because there are too many. When scanning an older project for the first time, hundreds of findings often appear. The temptation is great to postpone the topic. Instead, start with the critical and high findings (CVSS 7.0 and above) and work your way forward. It is better to fix 20 critical vulnerabilities than to leave 200 on the list because the volume feels discouraging.

No timeframes for remediation. Without defined deadlines, findings remain on the list. Define SLAs: Critical (CVSS 9.0+) within 48 hours, High (CVSS 7.0-8.9) within 7 days, Medium (CVSS 4.0-6.9) within 30 days.

Not committing lock files. Without a lock file in the repository, each build can download different versions. This makes dependency scanning unreliable and leads to non-reproducible builds. Always commit lock files to the repository.

Forgetting legacy projects. Older applications that are still running in production but are no longer actively developed do not receive dependency updates. They become ticking time bombs. Include maintenance projects in the regular scan cycle and link the results to your patch management.

Further Reading

Document your vulnerability management

ISMS Lite helps you document your dependency scanning process, track vulnerability assessments, and demonstrate compliance for audits.

Install now