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

feat(linter): add a check for affected field #295

Merged
merged 2 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion tools/osv-linter/internal/checks/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type CheckDef struct {

// Config defines the configuration for a check.
type Config struct {
Verbose bool
Verbose bool
Ecosystems []string
}

Expand Down Expand Up @@ -91,6 +91,7 @@ var Collections = []CheckCollection{
Name: "ALL",
Description: "all checks currently defined",
Checks: []*CheckDef{
CheckRecordHasAffected,
CheckRangeHasIntroducedEvent,
CheckRangeIsDistinct,
CheckPackageExists,
Expand All @@ -102,6 +103,7 @@ var Collections = []CheckCollection{
Name: "offline",
Description: "checks that do not have remote data dependencies",
Checks: []*CheckDef{
CheckRecordHasAffected,
CheckRangeHasIntroducedEvent,
CheckRangeIsDistinct,
CheckPackagePurlValid,
Expand Down
6 changes: 3 additions & 3 deletions tools/osv-linter/internal/checks/ranges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/google/go-cmp/cmp/cmpopts"
)

func loadTestData(filename string) *gjson.Result {
func LoadTestData(filename string) *gjson.Result {
content, err := os.ReadFile(filename)
if err != nil {
panic(err)
Expand All @@ -31,14 +31,14 @@ func TestRangeHasIntroducedEvent(t *testing.T) {
{
name: "A compliant file",
args: args{
json: loadTestData("../../test_data/CVE-2023-41045.json"),
json: LoadTestData("../../test_data/CVE-2023-41045.json"),
},
wantFindings: nil,
},
{
name: "A file without an introduced event",
args: args{
json: loadTestData("../../test_data/nointroduced-CVE-2023-41045.json"),
json: LoadTestData("../../test_data/nointroduced-CVE-2023-41045.json"),
},
wantFindings: []CheckError{{Message: "missing 'introduced' object in event"}},
},
Expand Down
21 changes: 21 additions & 0 deletions tools/osv-linter/internal/checks/record.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package checks

import (
"github.com/tidwall/gjson"
)

var CheckRecordHasAffected = &CheckDef{
Code: "A0001",
Name: "affected-data-exists",
Description: "every record has affected data",
Check: RecordHasAffected,
}

// RecordHasAffected checks if the 'affected' field exists in the JSON and is not an empty array.
func RecordHasAffected(json *gjson.Result, config *Config) (findings []CheckError) {
affectedEntries := json.Get("affected")
if !affectedEntries.Exists() || affectedEntries.String() == "[]" {
findings = append(findings, CheckError{Message: "Invalid Affected: affected filed cannot be null or empty"})
}
return findings
}
51 changes: 51 additions & 0 deletions tools/osv-linter/internal/checks/record_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package checks

import (
"testing"

"github.com/tidwall/gjson"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)

func TestAffectedField(t *testing.T) {
type args struct {
json *gjson.Result
}
tests := []struct {
name string
args args
wantFindings []CheckError
}{
{
name: "A compliant file",
args: args{
json: LoadTestData("../../test_data/CVE-2023-41045.json"),
},
wantFindings: nil,
},
{
name: "A file with an empty affected field",
args: args{
json: LoadTestData("../../test_data/SUSE-FU-2022:0444-1.json"),
},
wantFindings: []CheckError{{Message: "Invalid Affected: affected filed cannot be null or empty"}},
},
{
name: "A file without affected field",
args: args{
json: LoadTestData("../../test_data/RHSA-2022:0216.json"),
},
wantFindings: []CheckError{{Message: "Invalid Affected: affected filed cannot be null or empty"}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotFindings := RecordHasAffected(tt.args.json, &Config{Verbose: true})
if diff := cmp.Diff(tt.wantFindings, gotFindings, cmpopts.EquateErrors()); diff != "" {
t.Errorf("RecordHasAffected() mismatch (-want +got):\n%s", diff)
}
})
}
}
128 changes: 128 additions & 0 deletions tools/osv-linter/test_data/RHSA-2022:0216.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{
"id": "RHSA-2022:0216",
"summary": "Red Hat Security Advisory: Red Hat JBoss Enterprise Application Platform 7.4 security update",
"modified": "2024-09-01T17:42:35Z",
"published": "2024-09-01T17:42:35Z",
"related": [
"CVE-2021-44832",
"CVE-2021-45046",
"CVE-2021-45105"
],
"references": [
{
"type": "ADVISORY",
"url": "https://access.redhat.com/errata/RHSA-2022:0216"
},
{
"type": "ARTICLE",
"url": "https://access.redhat.com/security/updates/classification/#low"
},
{
"type": "ARTICLE",
"url": "https://access.redhat.com/jbossnetwork/restricted/listSoftware.html?downloadType=securityPatches&product=appplatform&version=7.4"
},
{
"type": "ARTICLE",
"url": "https://access.redhat.com/security/vulnerabilities/RHSB-2021-009"
},
{
"type": "ARTICLE",
"url": "https://access.redhat.com/solutions/6577421"
},
{
"type": "ARTICLE",
"url": "https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.4/"
},
{
"type": "ARTICLE",
"url": "https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.4/html-single/installation_guide/"
},
{
"type": "REPORT",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2032580"
},
{
"type": "REPORT",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2034067"
},
{
"type": "REPORT",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2035951"
},
{
"type": "ADVISORY",
"url": "https://access.redhat.com/security/data/csaf/v2/advisories/2022/rhsa-2022_0216.json"
},
{
"type": "REPORT",
"url": "https://access.redhat.com/security/cve/CVE-2021-44832"
},
{
"type": "ADVISORY",
"url": "https://www.cve.org/CVERecord?id=CVE-2021-44832"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44832"
},
{
"type": "ARTICLE",
"url": "https://issues.apache.org/jira/browse/LOG4J2-3293"
},
{
"type": "REPORT",
"url": "https://access.redhat.com/security/cve/CVE-2021-45046"
},
{
"type": "ADVISORY",
"url": "https://www.cve.org/CVERecord?id=CVE-2021-45046"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-45046"
},
{
"type": "ARTICLE",
"url": "https://access.redhat.com/security/cve/CVE-2021-44228"
},
{
"type": "ARTICLE",
"url": "https://logging.apache.org/log4j/2.x/security.html"
},
{
"type": "ARTICLE",
"url": "https://www.openwall.com/lists/oss-security/2021/12/14/4"
},
{
"type": "ARTICLE",
"url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog"
},
{
"type": "REPORT",
"url": "https://access.redhat.com/security/cve/CVE-2021-45105"
},
{
"type": "ADVISORY",
"url": "https://www.cve.org/CVERecord?id=CVE-2021-45105"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-45105"
},
{
"type": "ARTICLE",
"url": "https://issues.apache.org/jira/browse/LOG4J2-3230"
},
{
"type": "ARTICLE",
"url": "https://www.openwall.com/lists/oss-security/2021/12/19/1"
}
],
"schema_version": "1.6.0",
"severity": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H"
}
]
}
Loading
Loading