providers/snyk/schema/convert.go (132 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates. // // 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 schema import ( "github.com/facebookincubator/flog" nvd "github.com/facebookincubator/nvdtools/cvefeed/nvd/schema" "github.com/facebookincubator/nvdtools/wfn" ) const ( cveDataVersion = "4.0" ) func (advisory *Advisory) Convert() (*nvd.NVDCVEFeedJSON10DefCVEItem, error) { nvdItem := nvd.NVDCVEFeedJSON10DefCVEItem{ CVE: &nvd.CVEJSON40{ CVEDataMeta: &nvd.CVEJSON40CVEDataMeta{ ID: advisory.ID(), ASSIGNER: "snyk.io", }, DataFormat: "MITRE", DataType: "CVE", // TODO: maybe set this to SNYK-$LANG ? DataVersion: cveDataVersion, Description: &nvd.CVEJSON40Description{ DescriptionData: []*nvd.CVEJSON40LangString{ { Lang: "en", Value: advisory.Description, }, }, }, Problemtype: advisory.newProblemType(), References: advisory.newReferences(), }, Configurations: advisory.newConfigurations(), Impact: &nvd.NVDCVEFeedJSON10DefImpact{ BaseMetricV3: &nvd.NVDCVEFeedJSON10DefImpactBaseMetricV3{ CVSSV3: &nvd.CVSSV30{ VectorString: advisory.CVSSV3, BaseScore: advisory.CvssScore, }, }, }, LastModifiedDate: snykTimeToNVD(advisory.ModificationTime), PublishedDate: snykTimeToNVD(advisory.PublicationTime), } return &nvdItem, nil } func (advisory *Advisory) ID() string { return advisory.SnykID } func (advisory *Advisory) newProblemType() *nvd.CVEJSON40Problemtype { if len(advisory.Cwes) == 0 { return nil } pt := &nvd.CVEJSON40Problemtype{ ProblemtypeData: []*nvd.CVEJSON40ProblemtypeProblemtypeData{ { Description: make([]*nvd.CVEJSON40LangString, len(advisory.Cwes)), }, }, } for i, cwe := range advisory.Cwes { pt.ProblemtypeData[0].Description[i] = &nvd.CVEJSON40LangString{ Lang: "en", Value: cwe, } } return pt } func (advisory *Advisory) newReferences() *nvd.CVEJSON40References { if len(advisory.References) == 0 { return nil } nrefs := 1 + len(advisory.References) + len(advisory.Cves) refs := &nvd.CVEJSON40References{ ReferenceData: make([]*nvd.CVEJSON40Reference, 0, nrefs), } addRef := func(name, url string) { refs.ReferenceData = append(refs.ReferenceData, &nvd.CVEJSON40Reference{ Name: name, URL: url, }) } if advisory.Title != "" && advisory.URL != "" { addRef(advisory.Title, advisory.URL) } for _, ref := range advisory.References { addRef(ref.Title, ref.URL) } for _, cve := range advisory.Cves { addRef(cve, "") } return refs } func (advisory *Advisory) newConfigurations() *nvd.NVDCVEFeedJSON10DefConfigurations { nodes := []*nvd.NVDCVEFeedJSON10DefNode{ &nvd.NVDCVEFeedJSON10DefNode{Operator: "OR"}, } var err error var product string if product, err = wfn.WFNize(advisory.Package); err != nil { flog.Errorf("can't wfnize %q\n", advisory.Package) product = advisory.Package } cpe := wfn.Attributes{Part: "a", Product: product} cpe22URI := cpe.BindToURI() cpe23URI := cpe.BindToFmtString() for _, versions := range advisory.VulnerableVersions { vRanges, err := parseVersionRange(versions) if err != nil { flog.Errorf("could not generate configuration for item %s, vulnerable ver %q: %v", advisory.SnykID, versions, err) continue } for _, vRange := range vRanges { node := &nvd.NVDCVEFeedJSON10DefCPEMatch{ CPEName: []*nvd.NVDCVEFeedJSON10DefCPEName{ &nvd.NVDCVEFeedJSON10DefCPEName{ Cpe22Uri: cpe22URI, Cpe23Uri: cpe23URI, }, }, Cpe23Uri: cpe23URI, VersionStartIncluding: vRange.minVerIncl, VersionStartExcluding: vRange.minVerExcl, VersionEndIncluding: vRange.maxVerIncl, VersionEndExcluding: vRange.maxVerExcl, Vulnerable: true, } nodes[0].CPEMatch = append(nodes[0].CPEMatch, node) } } return &nvd.NVDCVEFeedJSON10DefConfigurations{ Nodes: nodes, } }