Software supply chains have become a focal point for attackers, as modern applications rely heavily on third-party and open-source dependencies. Organizations are adopting Software Bill of Materials (SBOM) documents to gain visibility into their software components. In this article, we explore SBOMs, why the CycloneDX format is recommended (and how it compares to SPDX), and how an SBOM can be leveraged to detect and prevent dependency confusion in your projects.
What is SBOM?
A Software Bill of Materials (SBOM) is a detailed, formally structured inventory of all components that make up a software product. It lists all libraries, packages, and modules — open-source and proprietary — and includes metadata such as versions, licenses, hashes, and dependency relationships. An SBOM enables:
- Vulnerability management — quickly identify components with known security flaws
- License compliance — track and verify open-source license obligations
- Supply chain transparency — improve auditability and trust in software
Several standards exist for representing SBOMs, the most common being SPDX and CycloneDX.
Why Use CycloneDX for SBOMs?
CycloneDX and SPDX are both industry-approved SBOM formats with distinct strengths:
Primary focus:
- CycloneDX: Application security, vulnerability workflows, and supply-chain risk analysis
- SPDX: License compliance, provenance, and legal auditing
Metadata depth:
- CycloneDX: Detailed component relationships, Vulnerability Exploitability eXchange (VEX) data, hashes, and custom metadata
- SPDX: Comprehensive license expressions, file checksums, and package provenance
Schema and tool support:
- CycloneDX: Lightweight JSON/XML, optimized for security tooling (Trivy, Syft, Dependency-Track)
- SPDX: RDF/JSON, widely adopted in open-source communities and legal workflows
Extensibility:
- CycloneDX: VEX (Vulnerability Exploitability eXchange), attestations, and custom data fields
- SPDX: Provenance tracking, license exception clauses, and rich license metadata
Ecosystem adoption:
- CycloneDX: Rapid growth across DevSecOps pipelines, strong support for automated security scans
- SPDX: Established in open-source governance, favored for compliance and audit use cases
Why prefer CycloneDX?
- Built with security use cases in mind: supports vulnerability (VEX) and attestation data.
- Simplified data model: easier integration into CI/CD and parsing by security tools.
- Rapidly growing ecosystem: many scanners and platforms generate or consume CycloneDX.
However, SPDX remains valuable where license compliance is paramount.
What is Dependency Confusion?
Dependency confusion attacks the supply chain to deliver malicious code into the development environment. Developers use package manager systems to download packages (dependencies) and build projects. Usually, developers add some packages to the build file and initiate installing or downloading those packages. Downloading happens from public repositories, most commonly npmjs.com and PyPI.org. Anyone can register and publish their packages.
For more details, see my earlier article: Dependency Confusion Detection & Mitigation.
Using SBOM to Detect Dependency Confusion
An SBOM enables a systematic check for name collisions between internal dependencies and public registries:
- Inventory: Generate an SBOM listing all dependencies (including private/internal ones).
- Identify internals: Determine which components should be internal based on naming conventions or repository metadata.
- Cross-check: Query public package registries (e.g., PyPI, npm) for each internal package name.
- Flag collisions: Any internal name found publicly is a potential dependency confusion risk.
- Review and remediate: Confirm the legitimacy of public packages, tighten registry configurations, reserve names, or rename internal packages.
SBOM Components and PURLs (Package URLs)
CycloneDX defines components (dependencies) and uses Package URLs (purls) — a standardized identifier — to describe each component. A purl has the format:
pkg://@
For example:
pkg:npm/lodash@4.17.21
PURLs enable automated registry lookups by indicating the ecosystem (npm
, pypi
, etc.), package name, and version. Parsing purls is the first step in programmatically checking registry existence.
Generating SBOMs with Trivy
Trivy is a widely adopted vulnerability scanner that also generates CycloneDX SBOMs:
- Scan filesystem/project:
trivy fs --format cyclonedx -o sbom.json ./
- Scan container image:
trivy image --format cyclonedx -o sbom.json alpine:latest
- Dedicated SBOM command (recent versions):
trivy sbom --output sbom.json ./
Integrate Trivy into your CI/CD to produce up-to-date SBOMs for every build.
Detecting Dependency Confusion with SBOM Analysis
Combine analysis and automation under one workflow:
-
Parse SBOM JSON: Extract the
components
array. - Extract purls: For each component, parse the purl to get the ecosystem and name.
- Query public APIs:
-
PyPI:
GET https://pypi.org/pypi/<name>/json
→ 404 means not found. -
npm:
GET https://registry.npmjs.org/<name>
→ 404 means not found.
- Classify results:
- Not found: internal package name unclaimed publicly (reserve name).
- Found: check if it’s expected (open-source) or unexpected (collision).
- Automate: Use a script (e.g., Python) to iterate purls, perform HTTP checks, and generate a report.
This combined approach ensures repeatable, scalable, and CI-integrated detection. The fully automated solution is available in the dedicated GitHub repository.
Best Practices for Preventing Dependency Confusion
Drawing on strategies from my Dependency Confusion Detection & Mitigation (April 2025) article:
- Reserve internal package names on public registries by publishing a placeholder or dummy package (prevents attackers from squatting).
-
Use scoped or uniquely namespaced packages (e.g.,
@myorg/internal-lib
on npm) to avoid generic collisions. - Enforce registry authentication and pinning in build pipelines — limit installs to authenticated private registries when fetching internal dependencies.
- Implement periodic SBOM-based audits to detect new name collisions and dependency anomalies.
- Monitor package version inflation: if a public package suddenly jumps to a high version, treat it as suspicious.
These practices, linked with SBOM detection workflows, create a robust defense-in-depth against dependency confusion.
At the end
SBOMs offer critical transparency into software dependencies. By generating SBOMs in CycloneDX format (e.g., via Trivy) and performing automated analysis of public registry presence, teams can effectively detect and mitigate dependency confusion risks. Expanding SBOM-based checks into CI/CD and adopting best practices — reserving names and enforcing private registry pinning — ensures proactive defense against evolving supply chain attacks. Stay vigilant and integrate SBOM analysis into your security processes to keep your codebase safe.
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.