anchore / anchore/syft

Using file as a version in a package-lock.json creates a SPDX package without versionInfo (Non-NTIA compliant)

Open
#2,015 4 comments 1 reaction 0 assignees View on GitHub
bug ecosystem:javascript enhancement
Dominant language
Go
Stars
9.6k
Forks
954
Avg merge
1d 5h
Merged PRs (30d)
42

Description

**What happened**:
In the case of scanning a NPM project with a package-lock.json using a file as a version.

_package-lock.json_
```
"../tools/local-tool": {
      "version": "0.1.0"
    },
    "node_modules/local-tool": {
      "resolved": "../tools/local-tool",
      "link": true
    }
```

_../tools/local-tool/package.json_
```
{
  "name": "local-tool",
  "version": "0.1.0",
  "description": "A local tool"
}
```

It generates two block in the final spdx-json SBOM generated on scanning _package-lock.json_
One block without `versionInfo` (Non NTIA compliant)
```
{
"name": "local-tool",
"SPDXID": "SPDXRef-Package-npm-local-tool-5607b76624f7aa40",
"downloadLocation": "NOASSERTION",
"sourceInfo": "acquired package info from installed node module manifest file: package-lock.json",
"licenseConcluded": "NONE",
"licenseDeclared": "NONE",
"copyrightText": "NOASSERTION",
"externalRefs": [...]
},
```
One block with `versionInfo` (NTIA compliant)
```
{
"name": "../tools/local-tool",
"SPDXID": "SPDXRef-Package-npm-..-tools-local-tool-e372d15bc46dbad5",
"versionInfo": "0.1.0",
"downloadLocation": "NOASSERTION",
"sourceInfo": "acquired package info from installed node module manifest file: package-lock.json",
"licenseConcluded": "NONE",
"licenseDeclared": "NONE",
"copyrightText": "NOASSERTION",
"externalRefs": [...]
},
```

**What you expected to happen**:

I would expect Syft to generate NTIA compliant SBOM with either:
Two blocks with `versionInfo` defined
or
One block with `versionInfo` defined (as it looks like they are duplicated)

**Steps to reproduce the issue**:

Create this folder structure
package.json (with a reference to /tools/package.json instead of the version)
```
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"local-tool": "file:../tools/local-tool"
}
}
```
tools/package.json
```
{
"name": "local-tool",
"version": "0.1.0",
"description": "A local tool"
}
```
Then run `npm install` to generate ./package-lock.json
Then execute `syft .`

**Anything else we need to know?**:
I used https://github.com/spdx/ntia-conformance-checker to check the compliance of the generated SBOMs
With that result
```
Is this SBOM NTIA minimum element conformant? False

Individual elements | Status
-------------------------------------------------------
All component names provided? | True
All component versions provided? | False
All component identifiers provided? | True
All component suppliers provided? | True
SBOM author name provided? | True
SBOM creation timestamp provided? | True
Dependency relationships provided? | True

Components missing a version: local-tool
```

**Environment**:
- Output of `syft version`: v0.77.0
- OS (e.g: `cat /etc/os-release` or similar): Ubuntu

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue with the shown package.json, tools/package.json, and generated package-lock.json, then run syft . and inspect the SPDX JSON output with the NTIA conformance checker. Trace how the file dependency and linked node module are represented; done means the duplicate local-tool packages are resolved or both emitted with versionInfo.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, node.js
Domain
cli, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.