ASVS 5.0 V15.1.2 is a Level 2 requirement. You must maintain an inventory catalog, such as a software bill of materials (SBOM), of all third party libraries in use. You must also verify that components come from pre defined, trusted and continually maintained repositories.
Two parts: know what you ship, and know where it came from.
Why it matters
When a new vulnerability lands, the first question is "are we affected?". Without an inventory, you answer by searching repositories for hours. With one, it is a query.
Source matters too. Dependency confusion, typosquatted names and abandoned packages all work because projects accept anything that resolves. A list of approved registries and a rule that anything else is rejected closes that door.
How to implement it
Generate the SBOM from the build, not by hand, and store it with each release.
# CycloneDX for a Node project
npx @cyclonedx/cyclonedx-npm --output-file sbom.cdx.json
# Python
cyclonedx-py environment -o sbom.cdx.json
# Container image
syft myapp:1.4.2 -o cyclonedx-json > sbom.cdx.json
Include transitive dependencies, versions and, ideally, hashes and package URLs.
Pin sources so builds cannot pull from elsewhere:
# .npmrc
registry=https://registry.internal.example.com/
@yourorg:registry=https://registry.internal.example.com/
# pip.conf
[global]
index-url = https://pypi.internal.example.com/simple
Use lock files with integrity hashes, and fail CI when the lock file and the manifest disagree:
npm ci
pip install --require-hashes -r requirements.txt
Add an allowlist check to the pipeline. For npm, every package in the lock file records the URL it was resolved from:
import json, sys
from urllib.parse import urlparse
approved = {"registry.internal.example.com"}
lock = json.load(open("package-lock.json"))
bad = []
for path, pkg in lock.get("packages", {}).items():
url = pkg.get("resolved")
if url and urlparse(url).hostname not in approved:
bad.append(path)
if bad:
sys.exit("unapproved sources: " + ", ".join(bad))
Other ecosystems have equivalents in their lock files. The point is that the check exists and fails the build.
You can start without installing anything: the free in browser dependency scan at gold.safeguard.sh/scan lists your dependencies and their known issues, and the dependency inventory demo shows what a maintained inventory looks like.
Click through it at your own pace, or open it full screen.
How to test it
- Ask for the SBOM of the version currently in production. It must exist and match that version.
- Pick five libraries at random from the running application and find each in the SBOM.
- For each, confirm the registry it was fetched from is on the approved list.
- Try adding a dependency from an unapproved source in a branch. The pipeline should reject it.
- Check how old the SBOM is relative to the last deploy.
Common mistakes
- An SBOM generated once for an audit and never refreshed.
- Listing direct dependencies only.
- Approving a registry but allowing a fallback to the public index, which enables dependency confusion.
- No view into base images and system packages in containers.
- Treating a package as maintained because it is popular, without checking release activity.
Quick check
Which SBOM format should I use?
The requirement names no format. CycloneDX and SPDX are both common, so pick the one your tools and customers can read.
Is a lock file an inventory?
It is a start, since it records exact versions, but it does not cover container layers or give you a portable, queryable catalog.