Dynamic Software Composition Analysis: Securing npm Packages with dSCA

This is Part 1 of a 3-part series on uncovering hidden risks in open-source software with dynamic SCA (dSCA). Stay tuned for our open-source tool release!

Introduction: The Hidden Risks in Open-Source Software

Supply chain attacks, like the infamous 2021 Log4j exploit or npm package compromises, have rocked the cybersecurity world, exposing vulnerabilities in modern CI/CD pipelines. Traditional Software Composition Analysis (SCA)—an automated process that identifies open-source software in a codebase to evaluate security, license compliance, and code quality—relies heavily on static analysis Black Duck, 2025. While effective for known vulnerabilities, static SCA misses dynamic behaviors, such as packages fetching remote binaries or scripts during installation. These actions can introduce malicious code, enable data exfiltration, or establish command-and-control (C2) infrastructure—terms that describe unauthorized data theft or remote attacker control.

Enter Dynamic Software Composition Analysis (dSCA), a service developed by NR Labs to analyze external resources accessed during npm package installation. Unlike static SCA, dSCA captures real-time behaviors, such as suspicious DNS lookups or remote binary downloads. In this series, we’ll walk through how dSCA uncovered risky behaviors in the npm ecosystem and share an open-source tool, tentatively called dSCA Analyzer, to empower developers to secure their pipelines. This post focuses on Phase 1: identifying npm packages that perform unexpected DNS lookups during installation.


Why It Matters
: If you’re a DevOps engineer, security professional, or developer, understanding these risks is critical to protecting your software supply chain. Let’s dive in!

Why Dynamic Analysis Matters

Static SCA scans a codebase for known vulnerabilities but can’t detect runtime behaviors. For example, npm’s package manager allows packages to:

  • Fetch and execute remote binaries via tools like @mapbox/node-pre-gyp.
  • Run scripts during installation that download external resources npm Docs, 2025.
  • Access external domains, potentially altering functionality or leaking sensitive data.

These behaviors are blind spots for static SCA. A malicious package could appear benign in a static scan but download harmful code during installation. dSCA addresses this by monitoring network traffic and resource access in real time, ensuring no stone is left unturned.


Phase 1: Identifying Suspicious npm Packages

NR Labs analyzed 3,123,890 npm packages to identify those performing DNS lookups to domains other than the official npm registry (registry.npmjs.org). Here’s how we did it:


Step 1: Filtering Active Packages

We started with a list of all npm package names from the daily-updated all-the-package-names package, provided as a JSON file (names.json). To focus on actively used packages, we queried the npm API to confirm each package had at least 1,000 downloads over the past six months. This ensured our analysis targeted packages relevant to real-world CI/CD pipelines.


Step 2: Capturing DNS Traffic

For each active package, we:

  • Spun up a Docker container running the tcpdump utility to monitor network traffic.
  • Installed the package and recorded all network activity in a .pcap file.
  • Analyzed the .pcap file for DNS lookups using a custom Python application.
  • Logged packages that queried domains other than registry.npmjs.org in a SQLite database.

Why Non-NPM Domains Are Suspicious: Legitimate npm packages typically interact only with the npm registry during installation. Lookups to external domains may indicate a package is fetching remote resources, such as binaries or scripts, which could be malicious.


Figure 1
(below) illustrates this process:

Diagram illustrating the dSCA process for capturing DNS traffic during npm package installation

Alt text: Diagram showing the workflow of dSCA Phase 1, where npm packages are installed in a Docker container, network traffic is captured using tcpdump, and DNS lookups are analyzed and stored in a SQLite database.


Example Code Snippet

Here’s a simplified version of the Python code used to parse DNS traffic from .pcap files:

python

from scapy.all import rdpcap, DNS

def parse_pcap(pcap_file):

   packets = rdpcap(pcap_file)

   for pkt in packets:

       if pkt.haslayer(DNS) and pkt[DNS].qd.qname != b'registry.npmjs.org.':

           return pkt[DNS].qd.qname.decode()

   return None

This snippet checks for DNS queries to non-npm domains, flagging suspicious packages for further analysis.


Key Findings

Out of 3,123,890 packages analyzed, 855 performed DNS lookups to domains other than the npm registry. While this is a small fraction (0.027%), these packages represent potential vulnerabilities in the npm ecosystem, as external domains could host malicious resources.


By the Numbers
:

Metric

Total Packages Analyzed: Value 3,123,890

Packages with Non-NPM DNS Lookups: Value 855

Percentage of Suspicious Packages: Value 0.027%

What’s Next?

In Part 2, we’ll explore Phase 2 of our dSCA analysis: decrypting TLS traffic to uncover the exact remote resources these 855 packages accessed and analyzing them for malicious activity. We’ll also share insights into how attackers might exploit these behaviors. By the end of this series, we’ll release dSCA Analyzer, an open-source tool to help you audit npm packages in your own pipeline.


Try It Yourself
: Install a small npm package (e.g., lodash) in a controlled environment and use a tool like Wireshark to observe its network traffic. You might be surprised by what you find!


Stay Tuned
: Share this post with your team to spark a conversation about securing your CI/CD pipeline, and let us know your thoughts in the comments below!


References