SPDX 2.3 serializer writes invalid SPDXIDs when node IDs come from CycloneDX bom-refs
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 334
- Forks
- 64
- Avg merge
- 1d 34m
- Merged PRs (30d)
- 19
Description
What happens
When a document read from CycloneDX is written as SPDX 2.3, the SPDX serializer uses each node's ID verbatim as the SPDXID (common.ElementID(node.Id) in pkg/native/serializers/serializer_spdx23.go). Node IDs that came from CycloneDX are bom-ref values, which are often purls, so the output contains identifiers such as:
"SPDXID": "SPDXRef-pkg:cargo/itoa@1.0.11?package-id=000cabec8808ac43"
SPDX 2.3 (clauses 7.2, 8.2) restricts the part after SPDXRef- to letters, digits, . and -, so the document does not validate against the SPDX 2.3 JSON schema. Protobom's own SPDX reader accepts it, so a CycloneDX → SPDX → Protobom round trip does not reveal the problem.
Reproduce (v0.6.1; the same code is on main)
- Take any CycloneDX JSON whose
bom-refs are purls — Syft (syft dir:. -o cyclonedx-json) and cdxgen both produce these. reader.New().ParseStream(...), thenwriter.New(writer.WithFormat(formats.SPDX23JSON)).WriteStream(doc, w).- Check the
SPDXID,spdxElementIdandrelatedSpdxElementvalues against^SPDXRef-[A-Za-z0-9.-]+$.
With a 7-package Cargo.lock SBOM from Syft 1.52.0, 6 of 7 package SPDXIDs fail the pattern (the seventh has a plain hex bom-ref).
Expected
SPDX serializers emit valid identifiers whatever the node IDs look like — for example by sanitising the ID (replacing disallowed characters and adding a short hash of the original to keep it unique) and applying the same mapping to relationships and documentDescribes.
Workaround we use
We rewrite all node IDs to an SPDX-safe form after parsing and keep the original bom-ref as a node property.
Happy to send a PR if you agree on the approach.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in pkg/native/serializers/serializer_spdx23.go and trace writer.New(writer.WithFormat(formats.SPDX23JSON)).WriteStream after a CycloneDX document is parsed. Reproduce the issue with purl-based bom-refs, then define and test a consistent SPDX-safe mapping for SPDXID, spdxElementId, relatedSpdxElement, and documentDescribes while preserving uniqueness and the original IDs as described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100