protobom / protobom/protobom

SPDX 2.3 serializer writes invalid SPDXIDs when node IDs come from CycloneDX bom-refs

Open
#478 0 comments 0 reactions 0 assignees View on GitHub

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)
  1. Take any CycloneDX JSON whose bom-refs are purls — Syft (syft dir:. -o cyclonedx-json) and cdxgen both produce these.
  2. reader.New().ParseStream(...), then writer.New(writer.WithFormat(formats.SPDX23JSON)).WriteStream(doc, w).
  3. Check the SPDXID, spdxElementId and relatedSpdxElement values 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.