Skip to content
advanced Phase 8 · Application Security and Secure Coding

Dependency and Supply Chain Scanning

Catch vulnerable and malicious packages before they ship.

55m
0 problems
Topic Progress 0%

The Software Supply Chain Attack Surface

Supply Chain Attacks: When Your Dependencies Become the Attack Vector

Modern applications are built on hundreds or thousands of open-source dependencies. Each dependency is a potential attack vector — not just for known vulnerabilities, but for malicious code introduced by compromised maintainers, typosquatting, or build system attacks. Software Composition Analysis (SCA) is the practice of inventorying these dependencies and identifying risks before they reach production.

The Scale of the Problem

A typical modern application:

  • Direct dependencies: 20-100 packages
  • Transitive dependencies (dependencies of dependencies): 500-2,000+ packages
  • Each dependency is maintained by individuals or small teams with varying security practices
  • Dependencies are updated frequently, introducing new code that has not been security-reviewed

Types of Supply Chain Attacks

1. Known Vulnerabilities in Dependencies

The most common risk. A dependency has a published CVE, and the application uses a vulnerable version. Tools like npm audit, pip-audit, and OWASP Dependency-Check scan dependency manifests and match them against CVE databases.

2. Typosquatting

An attacker registers a package name that is a common misspelling of a popular package:

  • lodash vs lodahs
  • requests vs reqests
  • django vs dajngo

Developers who mistype a package name in their dependency manifest unknowingly install the malicious package.

3. Compromised Maintainers

An attacker gains access to a legitimate package maintainer's account (via credential theft, social engineering, or buying credentials on the dark web) and publishes a malicious update. The package name is legitimate, but the new version contains malicious code.

4. Dependency Confusion

An attacker publishes a package with the same name as an organization's internal private package to a public registry. If the package manager is misconfigured, it may install the public (malicious) package instead of the private one.

5. Build System Attacks

An attacker compromises the CI/CD pipeline or build tools (e.g., compromised GitHub Actions, malicious build scripts) to inject malicious code during the build process, even if all dependencies are clean.

Real-World Supply Chain Attacks

SolarWinds (2020): Attackers compromised the SolarWinds Orion build system and inserted a backdoor into a legitimate software update. The update was distributed to 18,000+ customers, including government agencies and Fortune 500 companies. The backdoor persisted for months before detection.

event-stream (2018): A popular npm package (event-stream, 2 million weekly downloads) was transferred to a new maintainer who added a malicious dependency (flatmap-stream) that stole cryptocurrency wallet data from applications using the package.

ua-parser-js (2021): A widely used npm package was compromised when the maintainer's account was hijacked. The malicious version included cryptominer and credential-stealing code.

Software Composition Analysis (SCA)

SCA tools automate the process of:

  1. Inventorying all dependencies (direct and transitive)
  2. Matching them against CVE databases (NVD, GitHub Advisory Database, etc.)
  3. Identifying license compliance issues
  4. Detecting outdated versions with known fixes
# npm audit — scans Node.js dependencies
npm audit

# pip-audit — scans Python dependencies
pip-audit

# OWASP Dependency-Check — multi-language scanning
dependency-check --scan ./project

Lockfiles, Integrity Checks, and CI/CD Integration

Securing the Dependency Pipeline

Preventing supply chain attacks requires controls at every stage: dependency selection, installation, build, and deployment. Lockfiles and integrity hashes are the foundation of a secure dependency pipeline.

Lockfiles and Integrity Hashes

A lockfile records the exact version and integrity hash of every dependency (including transitive dependencies). This prevents silently swapped packages — if the package content changes, the hash will not match and the installation will fail.

package-lock.json (npm):

{
  "lodash": {
    "version": "4.17.21",
    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
    "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
  }
}

The integrity field contains a hash of the package tarball. If the package is modified (even by a single byte), the hash will not match and npm will refuse to install it.

Pipfile.lock (Python):

{
  "requests": {
    "hashes": [
      "sha256:2574f0dd5482648402a6e2a54cd62230e40a44024a44030157854555555555555",
      "sha256:abc123..."
    ],
    "version": "==2.28.1"
  }
}

Best practices for lockfiles:

  1. Always commit lockfiles to version control
  2. Use npm ci (clean install) instead of npm install in CI/CD — it installs exactly what the lockfile specifies
  3. Regenerate lockfiles in a controlled environment, not on developer machines
  4. Review lockfile changes in pull requests

Private Registry and Dependency Confusion Prevention

To prevent dependency confusion attacks:

  1. Use scoped packages: Configure your package manager to always resolve your organization's private packages from your private registry:
// .npmrc
@myorg:registry=https://npm.myorg.com/
  1. Verify package sources: Ensure your package manager never falls back to public registries for private package names.

  2. Monitor public registries: Watch for packages registered with your organization's private package names.

CI/CD Integration

Integrate dependency scanning into the CI/CD pipeline to catch vulnerabilities before they reach production:

# GitHub Actions example
name: Dependency Scan
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Run npm audit
        run: npm audit --audit-level=high
        continue-on-error: false
      
      - name: Run Snyk scan
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high
      
      - name: OWASP Dependency-Check
        uses: dependency-check/Dependency-Check_Action@main
        with:
          project: 'my-project'
          path: '.'
          format: 'HTML'

Vulnerability Management Workflow

  1. Scan: Run SCA tools on every build
  2. Triage: Review findings — not all CVEs are exploitable in your context
  3. Prioritize: Focus on vulnerabilities that are:
    • Exploitable in your application's context
    • Have known exploits in the wild
    • Affect internet-facing components
  4. Remediate: Update to a patched version, apply a workaround, or accept the risk with documentation
  5. Monitor: Continuously scan for new CVEs affecting your dependencies

Practice: Analyze a Dependency Vulnerability

Your application uses log4j 2.14.1. A critical CVE (CVE-2021-44228, Log4Shell) is published with a CVSS score of 10.0. Describe the vulnerability, its impact, and your remediation plan.

Practice Problems

0 / 2 solved
Prevent Dependency Confusion

Your organization has an internal package `@myorg/utils` hosted on a private npm registry. An attacker publishes a malicious package with the same name to the public npm registry. Explain how this attack works and how to prevent it.

Solution
Dependency confusion works because npm (and other package managers) may resolve packages from multiple registries. If the private registry is not properly configured, npm may find the public malicious package and install it instead of the private one.

Prevention:
1. **Scope the private package**: Use a scoped package name (`@myorg/utils`) and configure `.npmrc` to always resolve that scope from the private registry:
   ```
   @myorg:registry=https://npm.myorg.com/
   ```
2. **Use npm's `publishConfig`**: In your package.json, specify the registry for your scope:
   ```json
   {
     "publishConfig": {
       "@myorg:registry": "https://npm.myorg.com/"
     }
   }
   ```
3. **Monitor public registries**: Use services like Sonatype Nexus Repository or npm's own monitoring to detect when someone publishes a package with your organization's private package names.
4. **Use lockfiles**: Commit `package-lock.json` to version control and use `npm ci` in CI/CD to ensure only locked versions are installed.
Integrate SCA into CI/CD

Design a CI/CD pipeline step that scans for vulnerable dependencies in a Python application. The pipeline should: 1. Install dependencies from the lockfile 2. Scan for known vulnerabilities 3. Fail the build if any critical or high-severity vulnerabilities are found 4. Generate a report for the team

Solution
```yaml
# GitHub Actions workflow
name: Python Dependency Scan
on: [push, pull_request]

jobs:
  dependency-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      
      - name: Install dependencies from lockfile
        run: |
          pip install pip-audit
          pip install -r requirements.txt
      
      - name: Scan for vulnerabilities
        id: audit
        run: |
          pip-audit --format=json --output=audit-report.json || true
          pip-audit --severity=high --desc
        continue-on-error: true
      
      - name: Check for critical/high vulnerabilities
        run: |
          if pip-audit --severity=high 2>&1 | grep -q 'Found'; then
            echo "Critical or high severity vulnerabilities found. Failing build."
            pip-audit --severity=high
            exit 1
          fi
      
      - name: Upload scan report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: dependency-audit-report
          path: audit-report.json
```

This pipeline installs from the lockfile, scans with `pip-audit`, fails the build on high/critical vulnerabilities, and uploads a report for the team to review.

Quiz

1. What is the purpose of a lockfile with integrity hashes?

Question 1 options

2. What is a dependency confusion attack?

Question 2 options

3. What was the primary attack vector in the SolarWinds breach (2020)?

Question 3 options

4. Why is `npm ci` preferred over `npm install` in CI/CD pipelines?

Question 4 options

5. Which of the following is NOT a type of supply chain attack?

Question 5 options

Flashcards

Question

What is Software Composition Analysis (SCA)?

Answer

The practice of inventorying all open-source dependencies (direct and transitive) and matching them against CVE databases to identify known vulnerabilities, license compliance issues, and outdated versions.

Question

What is a dependency confusion attack?

Answer

An attacker publishes a package with the same name as an organization's internal private package to a public registry. If the package manager is misconfigured, it may install the malicious public version instead of the private one.

Question

What was the SolarWinds attack (2020)?

Answer

Attackers compromised the SolarWinds Orion build system and inserted a backdoor (SUNBURST) into a legitimate software update. The digitally signed update was distributed to 18,000+ customers, including government agencies.

Question

Why is `npm ci` preferred over `npm install` in CI/CD?

Answer

It installs exactly what the lockfile specifies without resolving new versions or updating the lockfile. This ensures reproducible builds and prevents injection of malicious packages through the dependency resolution process.

Question

What is typosquatting in the context of software supply chains?

Answer

An attacker registers a package name that is a common misspelling of a popular package (e.g., `lodahs` instead of `lodash`). Developers who mistype the package name unknowingly install the malicious package.

Revision Notes

Key Takeaways

  • 1. SCA inventories all dependencies (direct and transitive) and matches them against CVE databases
  • 2. Lockfiles with integrity hashes prevent silently swapped packages — commit them to version control
  • 3. Use `npm ci` in CI/CD to install exactly what the lockfile specifies
  • 4. Dependency confusion attacks exploit misconfigured package managers resolving private package names from public registries
  • 5. Supply chain attacks (SolarWinds, event-stream) demonstrate that the build pipeline itself is an attack surface

Interview Tips

  • • Discuss a real-world supply chain attack (SolarWinds, event-stream, ua-parser-js) and explain the attack mechanism
  • • Explain how lockfiles with integrity hashes prevent silently swapped packages
  • • Describe how to prevent dependency confusion attacks with scoped packages and registry configuration
  • • Connect supply chain security to the OWASP Top 10 (A06: Vulnerable and Outdated Components) and explain why it is increasingly critical

Cheat Sheet

Dependency and Supply Chain Scanning Cheat Sheet

Phase: Application Security and Secure Coding | Level: advanced

Supply Chain Attack Types:

  • Known vulnerabilities (CVEs in dependencies)
  • Typosquatting — misspelled package names
  • Compromised maintainers — malicious updates to legitimate packages
  • Dependency confusion — public packages shadowing private packages
  • Build system attacks — compromised CI/CD pipelines

Defense:

  • SCA scanning in CI/CD (npm audit, pip-audit, OWASP Dependency-Check)
  • Lockfiles with integrity hashes — commit to version control
  • Use npm ci instead of npm install in CI/CD
  • Scope private packages to private registries
  • Monitor public registries for typosquatting
  • Review dependency changes in pull requests

Key points:

  • Software composition analysis inventories open-source libraries and matches them to CVEs
  • Lockfiles with integrity hashes prevent silently swapped transitive dependencies
  • Typosquatting and compromised maintainers make dependency review a supply-chain control
  • Integrate scanning into CI/CD for continuous monitoring

Tags: supply-chain, sca

Continue Learning

Before You Start

  • No prerequisites listed.