Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Adding CycloneDX 1.4 and 1.5 reporter #1014

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
af7560e
:sparkles: Creating a utility package to manager PURL mapping
marcwieserdev May 31, 2024
2666666
:test_tube: Adding integration tests on expected cyclonedx results
marcwieserdev May 31, 2024
6514c6b
:heavy_plus_sign: Adding testify dependency
marcwieserdev May 31, 2024
dddce28
:sparkles: Adding a package grouper mechanism to unify packages by PURL
marcwieserdev May 31, 2024
db6bbea
:sparkles: Adding CycloneDX 1.4 and 1.5 reporters
marcwieserdev May 31, 2024
85d1ae7
:sparkles: Wiring up everything
marcwieserdev May 31, 2024
816f18f
:recycle: Updating names, and turning error printing into an error
marcwieserdev Jun 7, 2024
41fcf20
:loud_sound: Adding a log through the reporter to warn about packages…
marcwieserdev Jun 7, 2024
88f639a
:fire: Removing Results grouped by PURL from VulnerabilityResults and…
marcwieserdev Jun 7, 2024
80875b3
:rewind: reverting test in the grouper package instead of the grouper…
marcwieserdev Jun 7, 2024
0c0784e
:test_tube: Updating snapshot after removal of ResultsByPURL
marcwieserdev Jun 7, 2024
02637ea
:rotating_light: Fixing linting issues
marcwieserdev Jun 7, 2024
ee4cdfb
:bulb: Adding a comment to explain what GroupByPURL does
marcwieserdev Jun 7, 2024
b1e664e
:recycle: Moving GroupByPURL to the internal/utility/purl package and…
marcwieserdev Jun 20, 2024
1aea667
:white_check_mark: Update snaps with new vuln changes
marcwieserdev Jun 20, 2024
96db5ac
Stopped using testify
marcwieserdev Jun 20, 2024
d71e01e
:truck: Rename BomCreator type to include the SBOM format (CycloneDX)
marcwieserdev Jun 21, 2024
e6e96b5
Set the json encoding format to multiline to increase readability
marcwieserdev Jun 21, 2024
9ece40a
:camera_flash: Updating snapshots with latest multiline json format c…
marcwieserdev Jun 21, 2024
a69b437
Merge remote-tracking branch 'upstream/main' into marc.wieser/Adding_…
marcwieserdev Jun 21, 2024
eff3a57
:white_check_mark: Checking snapshot diff to align with main branch a…
marcwieserdev Jun 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 163 additions & 1 deletion cmd/osv-scanner/__snapshots__/main_test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,43 @@ Scanned <rootdir>/fixtures/locks-many/package-lock.json file and found 1 package
---

[TestRun/#06 - 2]
unsupported output format "unknown" - must be one of: table, json, markdown, sarif, gh-annotations
unsupported output format "unknown" - must be one of: table, json, markdown, sarif, gh-annotations, cyclonedx-1-4, cyclonedx-1-5

---

[TestRun/Empty_cyclonedx_1.4_output - 1]
{
"$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"version": 1,
"components": [],
"vulnerabilities": []
}

---

[TestRun/Empty_cyclonedx_1.4_output - 2]
Scanning dir ./fixtures/locks-many/composer.lock
Scanned <rootdir>/fixtures/locks-many/composer.lock file and found 1 package

---

[TestRun/Empty_cyclonedx_1.5_output - 1]
{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [],
"vulnerabilities": []
}

---

[TestRun/Empty_cyclonedx_1.5_output - 2]
Scanning dir ./fixtures/locks-many/composer.lock
Scanned <rootdir>/fixtures/locks-many/composer.lock file and found 1 package

---

Expand Down Expand Up @@ -246,6 +282,132 @@ Attempted to scan lockfile but failed: <rootdir>/fixtures/locks-many-with-invali

---

[TestRun/cyclonedx_1.4_output - 1]
{
"$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"version": 1,
"components": [
{
"bom-ref": "pkg:composer/league/[email protected]",
"type": "library",
"name": "league/flysystem",
"version": "1.0.8",
"licenses": [],
"purl": "pkg:composer/league/[email protected]"
}
],
"vulnerabilities": [
{
"id": "GHSA-9f46-5r25-5wfm",
"references": [
{
"id": "CVE-2021-32708",
"source": {}
}
],
"ratings": [
{
"method": "CVSSv3",
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
}
],
"description": "Time-of-check Time-of-use (TOCTOU) Race Condition in league/flysystem",
"detail": "### Impact/n/nThe whitespace normalisation using in 1.x and 2.x removes any unicode whitespace. Under certain specific conditions this could potentially allow a malicious user to execute code remotely./n/nThe conditions: /n/n- A user is allowed to supply the path or filename of an uploaded file./n- The supplied path or filename is not checked against unicode chars./n- The supplied pathname checked against an extension deny-list, not an allow-list./n- The supplied path or filename contains a unicode whitespace char in the extension./n- The uploaded file is stored in a directory that allows PHP code to be executed./n/nGiven these conditions are met a user can upload and execute arbitrary code on the system under attack./n/n### Patches/n/nThe unicode whitespace removal has been replaced with a rejection (exception)./n/nThe library has been patched in:/n- 1.x: https://github.com/thephpleague/flysystem/commit/f3ad69181b8afed2c9edf7be5a2918144ff4ea32/n- 2.x: https://github.com/thephpleague/flysystem/commit/a3c694de9f7e844b76f9d1b61296ebf6e8d89d74/n/n### Workarounds/n/nFor 1.x users, upgrade to 1.1.4. For 2.x users, upgrade to 2.1.1./n",
"advisories": [
{
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-32708"
}
],
"published": "2021-06-29T03:13:28Z",
"updated": "2024-02-16T08:21:35Z",
"credits": {
"organizations": []
},
"affects": [
{
"ref": "pkg:composer/league/flysystem"
},
{
"ref": "pkg:composer/league/flysystem"
}
]
}
]
}

---

[TestRun/cyclonedx_1.4_output - 2]
Scanning dir ./fixtures/locks-insecure
Scanned <rootdir>/fixtures/locks-insecure/composer.lock file and found 1 package

---

[TestRun/cyclonedx_1.5_output - 1]
{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"bom-ref": "pkg:composer/league/[email protected]",
"type": "library",
"name": "league/flysystem",
"version": "1.0.8",
"licenses": [],
"purl": "pkg:composer/league/[email protected]"
}
],
"vulnerabilities": [
{
"id": "GHSA-9f46-5r25-5wfm",
"references": [
{
"id": "CVE-2021-32708",
"source": {}
}
],
"ratings": [
{
"method": "CVSSv3",
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
}
],
"description": "Time-of-check Time-of-use (TOCTOU) Race Condition in league/flysystem",
"detail": "### Impact/n/nThe whitespace normalisation using in 1.x and 2.x removes any unicode whitespace. Under certain specific conditions this could potentially allow a malicious user to execute code remotely./n/nThe conditions: /n/n- A user is allowed to supply the path or filename of an uploaded file./n- The supplied path or filename is not checked against unicode chars./n- The supplied pathname checked against an extension deny-list, not an allow-list./n- The supplied path or filename contains a unicode whitespace char in the extension./n- The uploaded file is stored in a directory that allows PHP code to be executed./n/nGiven these conditions are met a user can upload and execute arbitrary code on the system under attack./n/n### Patches/n/nThe unicode whitespace removal has been replaced with a rejection (exception)./n/nThe library has been patched in:/n- 1.x: https://github.com/thephpleague/flysystem/commit/f3ad69181b8afed2c9edf7be5a2918144ff4ea32/n- 2.x: https://github.com/thephpleague/flysystem/commit/a3c694de9f7e844b76f9d1b61296ebf6e8d89d74/n/n### Workarounds/n/nFor 1.x users, upgrade to 1.1.4. For 2.x users, upgrade to 2.1.1./n",
"advisories": [
{
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-32708"
}
],
"published": "2021-06-29T03:13:28Z",
"updated": "2024-02-16T08:21:35Z",
"credits": {
"organizations": []
},
"affects": [
{
"ref": "pkg:composer/league/flysystem"
},
{
"ref": "pkg:composer/league/flysystem"
}
]
}
]
}

---

[TestRun/cyclonedx_1.5_output - 2]
Scanning dir ./fixtures/locks-insecure
Scanned <rootdir>/fixtures/locks-insecure/composer.lock file and found 1 package

---

[TestRun/folder_of_supported_sbom_with_vulns - 1]
Scanning dir ./fixtures/sbom-insecure/
Scanned <rootdir>/fixtures/sbom-insecure/alpine.cdx.xml as CycloneDX SBOM and found 14 packages
Expand Down
22 changes: 22 additions & 0 deletions cmd/osv-scanner/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,28 @@ func TestRun(t *testing.T) {
args: []string{"", "--format", "markdown", "--config", "./fixtures/osv-scanner-empty-config.toml", "./fixtures/locks-many/package-lock.json"},
exit: 1,
},
// output format: cyclonedx 1.4
{
name: "Empty cyclonedx 1.4 output",
args: []string{"", "--format", "cyclonedx-1-4", "./fixtures/locks-many/composer.lock"},
exit: 0,
},
{
name: "cyclonedx 1.4 output",
args: []string{"", "--format", "cyclonedx-1-4", "--experimental-all-packages", "./fixtures/locks-insecure"},
exit: 1,
},
// output format: cyclonedx 1.5
{
name: "Empty cyclonedx 1.5 output",
args: []string{"", "--format", "cyclonedx-1-5", "./fixtures/locks-many/composer.lock"},
exit: 0,
},
{
name: "cyclonedx 1.5 output",
args: []string{"", "--format", "cyclonedx-1-5", "--experimental-all-packages", "./fixtures/locks-insecure"},
exit: 1,
},
// output format: unsupported
{
name: "",
Expand Down
21 changes: 21 additions & 0 deletions internal/utility/purl/composer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package purl

import (
"fmt"
"strings"

"github.com/google/osv-scanner/pkg/models"
)

func FromComposer(packageInfo models.PackageInfo) (namespace string, name string, err error) {
nameParts := strings.Split(packageInfo.Name, "/")
if len(nameParts) != 2 {
err = fmt.Errorf("invalid packagist package_name (%s)", packageInfo.Name)

return
}
namespace = nameParts[0]
name = nameParts[1]

return
}
78 changes: 78 additions & 0 deletions internal/utility/purl/composer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package purl_test

import (
"testing"

"github.com/google/osv-scanner/internal/utility/purl"

"github.com/google/osv-scanner/pkg/models"
)

func TestComposerExtraction_shouldExtractPackages(t *testing.T) {
t.Parallel()
testCase := struct {
packageInfo models.PackageInfo
expectedNamespace string
expectedName string
}{
packageInfo: models.PackageInfo{
Name: "symfony/yaml",
Version: "7.0.0",
Ecosystem: string(models.EcosystemPackagist),
Commit: "",
},
expectedNamespace: "symfony",
expectedName: "yaml",
}

namespace, name, err := purl.FromComposer(testCase.packageInfo)

if err != nil {
t.Errorf("Extraction didn't succeed, package has been wrongfully filtered")
}
if namespace != testCase.expectedNamespace {
t.Errorf("got %s; want %s", namespace, testCase.expectedNamespace)
}
if name != testCase.expectedName {
t.Errorf("got %s; want %s", name, testCase.expectedName)
}
}

func TestComposerExtraction_shouldFilterPackages(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
packageInfo models.PackageInfo
}{
{
name: "when_package_contains_less_than_2_parts",
packageInfo: models.PackageInfo{
Name: "symfony",
Version: "7.0.0",
Ecosystem: string(models.EcosystemPackagist),
Commit: "",
},
},
{
name: "when_package_have_no_name",
packageInfo: models.PackageInfo{
Name: "",
Version: "7.0.0",
Ecosystem: string(models.EcosystemPackagist),
Commit: "",
},
},
}

for _, test := range testCases {
testCase := test
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
_, _, err := purl.FromComposer(testCase.packageInfo)

if err == nil {
t.Errorf("Package %v should have been filtered\n", testCase.packageInfo)
}
})
}
}
24 changes: 24 additions & 0 deletions internal/utility/purl/golang.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package purl

import (
"fmt"
"strings"

"github.com/google/osv-scanner/pkg/models"
)

func FromGo(packageInfo models.PackageInfo) (namespace string, name string, err error) {
nameParts := strings.Split(packageInfo.Name, "/")
if len(nameParts) == 0 || len(packageInfo.Name) == 0 {
err = fmt.Errorf("invalid golang package_name (%s)", packageInfo.Name)

return
}

if len(nameParts) > 1 {
namespace = strings.Join(nameParts[:len(nameParts)-1], "/")
}
name = nameParts[len(nameParts)-1]

return
}
Loading
Loading