Supply Chain Risk Auditor

Supply Chain Risk Auditor

Supply Chain Risk Auditor automation and integration

Category: productivity Source: trailofbits/skills

Supply Chain Risk Auditor is a community skill for analyzing software supply chain security, covering dependency auditing, vulnerability scanning, license compliance, provenance verification, and risk scoring for open-source software dependencies.

What Is This?

Overview

Supply Chain Risk Auditor provides guidance on identifying and mitigating security risks in software dependency chains. It covers dependency auditing that inventories direct and transitive packages with version tracking, vulnerability scanning that checks packages against CVE databases for known exploits, license compliance that validates dependency licenses against project requirements, provenance verification that confirms package authenticity and publishing integrity, and risk scoring that rates dependencies based on maintenance activity and security history. The skill helps teams secure their software supply chain.

Who Should Use This

This skill serves security engineers auditing dependency risks, DevOps teams integrating supply chain checks into CI pipelines, and engineering managers establishing dependency governance.

Why Use It?

Problems It Solves

Transitive dependencies introduce vulnerabilities that direct auditing misses. Abandoned packages with known CVEs remain in dependency trees without detection. License conflicts between dependencies create legal exposure. Typosquatting and dependency confusion attacks inject malicious packages.

Core Highlights

Dependency mapper builds complete package trees with transitive resolution. Vulnerability checker scans against CVE and advisory databases. License validator checks compatibility across the dependency tree. Risk scorer rates packages by maintenance and security signals.

How to Use It?

Basic Usage

from dataclasses import (
  dataclass, field)

@dataclass
class Package:
  name: str
  version: str
  license: str
  deps: list = field(
    default_factory=list)

@dataclass
class Vulnerability:
  cve: str
  package: str
  severity: str
  fixed_in: str = ''

class SupplyChainAuditor:
  def __init__(self):
    self.packages: dict[
      str, Package] = {}
    self.vulns: list[
      Vulnerability] = []

  def add_package(
    self, pkg: Package
  ):
    self.packages[
      pkg.name] = pkg

  def add_vuln(
    self,
    vuln: Vulnerability
  ):
    self.vulns.append(vuln)

  def scan(self) -> list:
    findings = []
    for v in self.vulns:
      if v.package in (
        self.packages
      ):
        findings.append({
          'cve': v.cve,
          'package':
            v.package,
          'severity':
            v.severity,
          'current':
            self.packages[
              v.package]
            .version})
    return findings

  def license_check(
    self,
    allowed: list
  ) -> list:
    violations = []
    for p in (
      self.packages
      .values()
    ):
      if p.license not in (
        allowed
      ):
        violations.append({
          'package': p.name,
          'license':
            p.license})
    return violations

auditor = SupplyChainAuditor()
auditor.add_package(
  Package('lodash',
    '4.17.20', 'MIT'))
auditor.add_vuln(
  Vulnerability(
    'CVE-2021-23337',
    'lodash', 'high',
    '4.17.21'))
print(auditor.scan())

Real-World Examples

from dataclasses import (
  dataclass)
from datetime import (
  datetime, timedelta)

@dataclass
class PackageMetrics:
  name: str
  last_release: datetime
  maintainers: int
  open_vulns: int
  downloads: int

class RiskScorer:
  def score(
    self,
    pkg: PackageMetrics
  ) -> dict:
    risk = 0
    age = (
      datetime.now()
      - pkg.last_release)
    if age > timedelta(
      days=365
    ):
      risk += 30
    elif age > timedelta(
      days=180
    ):
      risk += 15
    if pkg.maintainers <= 1:
      risk += 20
    risk += min(
      pkg.open_vulns * 15,
      50)
    level = (
      'critical'
      if risk >= 70 else
      'high'
      if risk >= 50 else
      'medium'
      if risk >= 30 else
      'low')
    return {
      'package': pkg.name,
      'score': risk,
      'level': level}

scorer = RiskScorer()
pkg = PackageMetrics(
  'old-lib',
  datetime(2022, 1, 1),
  maintainers=1,
  open_vulns=2,
  downloads=500)
result = scorer.score(pkg)
print(
  f'{result["package"]}: '
  f'{result["level"]} '
  f'({result["score"]})')

Advanced Tips

Integrate dependency scanning into CI to catch vulnerable packages before they reach production. Pin dependency versions with lock files to prevent unexpected upgrades introducing vulnerabilities. Monitor dependency health metrics to identify packages at risk of abandonment.

When to Use It?

Use Cases

Audit a project's dependency tree for known vulnerabilities and license violations. Score package risk based on maintenance activity and security history. Enforce dependency policies in CI that block builds with high-risk packages.

Related Topics

Software supply chain, dependency management, CVE scanning, license compliance, SBOM, and package security.

Important Notes

Requirements

Access to package manifest files listing project dependencies. Vulnerability databases or advisory feeds for CVE lookups. License metadata available for dependency packages.

Usage Recommendations

Do: scan both direct and transitive dependencies since most vulnerabilities hide in indirect packages. Generate SBOMs for each release to maintain dependency records. Review high-risk findings promptly and establish upgrade policies.

Don't: ignore transitive dependency vulnerabilities since they are exploitable through direct package APIs. Assume popular packages are secure since download count does not correlate with security quality. Delay vulnerability remediation since exploits become available quickly after CVE disclosure.

Limitations

Vulnerability databases have lag between disclosure and advisory publication. Risk scoring uses heuristics that may not reflect actual exploitability. License detection depends on package metadata accuracy which varies across ecosystems.