-
Notifications
You must be signed in to change notification settings - Fork 2
/
report.go
171 lines (150 loc) · 5.18 KB
/
report.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package types
import (
"encoding/json"
v1 "github.com/google/go-containerregistry/pkg/v1" // nolint: goimports
ftypes "github.com/khulnasoft-lab/vul/pkg/fanal/types"
)
// Report represents a scan result
type Report struct {
SchemaVersion int `json:",omitempty"`
ArtifactName string `json:",omitempty"`
ArtifactType ftypes.ArtifactType `json:",omitempty"`
Metadata Metadata `json:",omitempty"`
Results Results `json:",omitempty"`
// SBOM
CycloneDX *ftypes.CycloneDX `json:"-"` // Just for internal usage, not exported in JSON
}
// Metadata represents a metadata of artifact
type Metadata struct {
Size int64 `json:",omitempty"`
OS *ftypes.OS `json:",omitempty"`
// Container image
ImageID string `json:",omitempty"`
DiffIDs []string `json:",omitempty"`
RepoTags []string `json:",omitempty"`
RepoDigests []string `json:",omitempty"`
ImageConfig v1.ConfigFile `json:",omitempty"`
}
// Results to hold list of Result
type Results []Result
type ResultClass string
type Compliance = string
type Format string
const (
ClassOSPkg ResultClass = "os-pkgs" // For detected packages and vulnerabilities in OS packages
ClassLangPkg ResultClass = "lang-pkgs" // For detected packages and vulnerabilities in language-specific packages
ClassConfig ResultClass = "config" // For detected misconfigurations
ClassSecret ResultClass = "secret" // For detected secrets
ClassLicense ResultClass = "license" // For detected package licenses
ClassLicenseFile ResultClass = "license-file" // For detected licenses in files
ClassCustom ResultClass = "custom"
ComplianceK8sNsa = Compliance("k8s-nsa")
ComplianceK8sCIS = Compliance("k8s-cis")
ComplianceK8sPSSBaseline = Compliance("k8s-pss-baseline")
ComplianceK8sPSSRestricted = Compliance("k8s-pss-restricted")
ComplianceAWSCIS12 = Compliance("aws-cis-1.2")
ComplianceAWSCIS14 = Compliance("aws-cis-1.4")
ComplianceDockerCIS = Compliance("docker-cis")
FormatTable Format = "table"
FormatJSON Format = "json"
FormatTemplate Format = "template"
FormatSarif Format = "sarif"
FormatCycloneDX Format = "cyclonedx"
FormatSPDX Format = "spdx"
FormatSPDXJSON Format = "spdx-json"
FormatGitHub Format = "github"
FormatCosignVuln Format = "cosign-vuln"
)
var (
SupportedFormats = []Format{
FormatTable,
FormatJSON,
FormatTemplate,
FormatSarif,
FormatCycloneDX,
FormatSPDX,
FormatSPDXJSON,
FormatGitHub,
FormatCosignVuln,
}
SupportedSBOMFormats = []Format{
FormatCycloneDX,
FormatSPDX,
FormatSPDXJSON,
FormatGitHub,
}
SupportedCompliances = []string{
ComplianceK8sNsa,
ComplianceK8sCIS,
ComplianceK8sPSSBaseline,
ComplianceK8sPSSRestricted,
ComplianceAWSCIS12,
ComplianceAWSCIS14,
ComplianceDockerCIS,
}
)
// Result holds a target and detected vulnerabilities
type Result struct {
Target string `json:"Target"`
Class ResultClass `json:"Class,omitempty"`
Type ftypes.TargetType `json:"Type,omitempty"`
Packages []ftypes.Package `json:"Packages,omitempty"`
Vulnerabilities []DetectedVulnerability `json:"Vulnerabilities,omitempty"`
MisconfSummary *MisconfSummary `json:"MisconfSummary,omitempty"`
Misconfigurations []DetectedMisconfiguration `json:"Misconfigurations,omitempty"`
Secrets []ftypes.SecretFinding `json:"Secrets,omitempty"`
Licenses []DetectedLicense `json:"Licenses,omitempty"`
CustomResources []ftypes.CustomResource `json:"CustomResources,omitempty"`
}
func (r *Result) MarshalJSON() ([]byte, error) {
// VendorSeverity includes all vendor severities.
// It would be noisy to users, so it should be removed from the JSON output.
for i := range r.Vulnerabilities {
r.Vulnerabilities[i].VendorSeverity = nil
}
// remove the Highlighted attribute from the json results
for i := range r.Misconfigurations {
for li := range r.Misconfigurations[i].CauseMetadata.Code.Lines {
r.Misconfigurations[i].CauseMetadata.Code.Lines[li].Highlighted = ""
}
}
// Notice the Alias struct prevents MarshalJSON being called infinitely
type ResultAlias Result
return json.Marshal(&struct {
*ResultAlias
}{
ResultAlias: (*ResultAlias)(r),
})
}
func (r *Result) IsEmpty() bool {
return len(r.Packages) == 0 && len(r.Vulnerabilities) == 0 && len(r.Misconfigurations) == 0 &&
len(r.Secrets) == 0 && len(r.Licenses) == 0 && len(r.CustomResources) == 0
}
type MisconfSummary struct {
Successes int
Failures int
Exceptions int
}
func (s MisconfSummary) Empty() bool {
return s.Successes == 0 && s.Failures == 0 && s.Exceptions == 0
}
// Failed returns whether the result includes any vulnerabilities, misconfigurations or secrets
func (results Results) Failed() bool {
for _, r := range results {
if len(r.Vulnerabilities) > 0 {
return true
}
for _, m := range r.Misconfigurations {
if m.Status == StatusFailure {
return true
}
}
if len(r.Secrets) > 0 {
return true
}
if len(r.Licenses) > 0 {
return true
}
}
return false
}