You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
clair/ext/vulnmdsrc/nvd/json.go

164 lines
4.4 KiB

// Copyright 2018 clair authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package nvd
import (
"fmt"
"strings"
log "github.com/sirupsen/logrus"
)
type nvd struct {
Entries []nvdEntry `json:"CVE_Items"`
}
type nvdEntry struct {
CVE nvdCVE `json:"cve"`
Impact nvdImpact `json:"impact"`
PublishedDateTime string `json:"publishedDate"`
}
type nvdCVE struct {
Metadata nvdCVEMetadata `json:"CVE_data_meta"`
}
type nvdCVEMetadata struct {
CVEID string `json:"ID"`
}
type nvdImpact struct {
BaseMetricV2 nvdBaseMetricV2 `json:"baseMetricV2"`
BaseMetricV3 nvdBaseMetricV3 `json:"baseMetricV3"`
}
type nvdBaseMetricV2 struct {
CVSSv2 nvdCVSSv2 `json:"cvssV2"`
}
type nvdCVSSv2 struct {
Score float64 `json:"baseScore"`
AccessVector string `json:"accessVector"`
AccessComplexity string `json:"accessComplexity"`
Authentication string `json:"authentication"`
ConfImpact string `json:"confidentialityImpact"`
IntegImpact string `json:"integrityImpact"`
AvailImpact string `json:"availabilityImpact"`
}
type nvdBaseMetricV3 struct {
CVSSv3 nvdCVSSv3 `json:"cvssV3"`
ExploitabilityScore float64 `json:"exploitabilityScore"`
ImpactScore float64 `json:"impactScore"`
}
type nvdCVSSv3 struct {
Score float64 `json:"baseScore"`
AttackVector string `json:"attackVector"`
AttackComplexity string `json:"attackComplexity"`
PrivilegesRequired string `json:"privilegesRequired"`
UserInteraction string `json:"userInteraction"`
Scope string `json:"scope"`
ConfImpact string `json:"confidentialityImpact"`
IntegImpact string `json:"integrityImpact"`
AvailImpact string `json:"availabilityImpact"`
}
var vectorValuesToLetters = map[string]string{
"NETWORK": "N",
"ADJACENT_NETWORK": "A",
"LOCAL": "L",
"HIGH": "H",
"MEDIUM": "M",
"LOW": "L",
"NONE": "N",
"SINGLE": "S",
"MULTIPLE": "M",
"PARTIAL": "P",
"COMPLETE": "C",
// CVSSv3 only
"PHYSICAL": "P",
"REQUIRED": "R",
"CHANGED": "C",
"UNCHANGED": "U",
}
func (n nvdEntry) Metadata() *NVDMetadata {
metadata := &NVDMetadata{
CVSSv2: NVDmetadataCVSSv2{
PublishedDateTime: n.PublishedDateTime,
Vectors: n.Impact.BaseMetricV2.CVSSv2.String(),
Score: n.Impact.BaseMetricV2.CVSSv2.Score,
},
CVSSv3: NVDmetadataCVSSv3{
Vectors: n.Impact.BaseMetricV3.CVSSv3.String(),
Score: n.Impact.BaseMetricV3.CVSSv3.Score,
ExploitabilityScore: n.Impact.BaseMetricV3.ExploitabilityScore,
ImpactScore: n.Impact.BaseMetricV3.ImpactScore,
},
}
if metadata.CVSSv2.Vectors == "" {
return nil
}
return metadata
}
func (n nvdEntry) Name() string {
return n.CVE.Metadata.CVEID
}
func (n nvdCVSSv2) String() string {
var str string
addVec(&str, "AV", n.AccessVector)
addVec(&str, "AC", n.AccessComplexity)
addVec(&str, "Au", n.Authentication)
addVec(&str, "C", n.ConfImpact)
addVec(&str, "I", n.IntegImpact)
addVec(&str, "A", n.AvailImpact)
str = strings.TrimSuffix(str, "/")
return str
}
func (n nvdCVSSv3) String() string {
var str string
addVec(&str, "AV", n.AttackVector)
addVec(&str, "AC", n.AttackComplexity)
addVec(&str, "PR", n.PrivilegesRequired)
addVec(&str, "UI", n.UserInteraction)
addVec(&str, "S", n.Scope)
addVec(&str, "C", n.ConfImpact)
addVec(&str, "I", n.IntegImpact)
addVec(&str, "A", n.AvailImpact)
str = strings.TrimSuffix(str, "/")
if len(str) > 0 {
return fmt.Sprintf("CVSS:3.0/%s", str)
}
return str
}
func addVec(str *string, vec, val string) {
if val != "" {
if let, ok := vectorValuesToLetters[val]; ok {
*str = fmt.Sprintf("%s%s:%s/", *str, vec, let)
} else {
log.WithFields(log.Fields{"value": val, "vector": vec}).Warning("unknown value for CVSS vector")
}
}
}