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