github.com/khulnasoft-lab/tunnel-db@v0.0.0-20231117205118-74e1113bd007/pkg/vulnsrc/ghsa/ghsa.go (about) 1 package ghsa 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "path/filepath" 7 "strings" 8 9 "golang.org/x/xerrors" 10 11 "github.com/khulnasoft-lab/tunnel-db/pkg/types" 12 "github.com/khulnasoft-lab/tunnel-db/pkg/vulnsrc/osv" 13 "github.com/khulnasoft-lab/tunnel-db/pkg/vulnsrc/vulnerability" 14 ) 15 16 const ( 17 sourceID = vulnerability.GHSA 18 platformFormat = "GitHub Security Advisory %s" 19 urlFormat = "https://github.com/advisories?query=type%%3Areviewed+ecosystem%%3A%s" 20 ) 21 22 var ( 23 ghsaDir = filepath.Join("ghsa", "advisories", "github-reviewed") 24 25 // Mapping between Tunnel ecosystem and GHSA ecosystem 26 ecosystems = map[types.Ecosystem]string{ 27 vulnerability.Composer: "Composer", 28 vulnerability.Go: "Go", 29 vulnerability.Maven: "Maven", 30 vulnerability.Npm: "npm", 31 vulnerability.NuGet: "NuGet", 32 vulnerability.Pip: "pip", 33 vulnerability.RubyGems: "RubyGems", 34 vulnerability.Cargo: "Rust", // different name 35 vulnerability.Erlang: "Erlang", 36 vulnerability.Pub: "Pub", 37 vulnerability.Swift: "Swift", 38 vulnerability.Cocoapods: "Swift", // Use Swift advisories for CocoaPods 39 } 40 ) 41 42 type DatabaseSpecific struct { 43 Severity string `json:"severity"` 44 } 45 46 type GHSA struct{} 47 48 func NewVulnSrc() GHSA { 49 return GHSA{} 50 } 51 52 func (GHSA) Name() types.SourceID { 53 return vulnerability.GHSA 54 } 55 56 func (GHSA) Update(root string) error { 57 dataSources := map[types.Ecosystem]types.DataSource{} 58 for ecosystem, ghsaEcosystem := range ecosystems { 59 src := types.DataSource{ 60 ID: sourceID, 61 Name: fmt.Sprintf(platformFormat, ghsaEcosystem), 62 URL: fmt.Sprintf(urlFormat, strings.ToLower(ghsaEcosystem)), 63 } 64 dataSources[ecosystem] = src 65 } 66 67 t, err := newTransformer(root) 68 if err != nil { 69 return xerrors.Errorf("transformer error: %w", err) 70 } 71 72 return osv.New(ghsaDir, sourceID, dataSources, t).Update(root) 73 } 74 75 type transformer struct { 76 // cocoaPodsSpecs is a map of Swift git URLs to CocoaPods package names. 77 cocoaPodsSpecs map[string][]string 78 } 79 80 func newTransformer(root string) (*transformer, error) { 81 cocoaPodsSpecs, err := walkCocoaPodsSpecs(root) 82 if err != nil { 83 return nil, xerrors.Errorf("CocoaPods spec error: %w", err) 84 } 85 return &transformer{ 86 cocoaPodsSpecs: cocoaPodsSpecs, 87 }, nil 88 } 89 90 func (t *transformer) TransformAdvisories(advisories []osv.Advisory, entry osv.Entry) ([]osv.Advisory, error) { 91 var specific DatabaseSpecific 92 if err := json.Unmarshal(entry.DatabaseSpecific, &specific); err != nil { 93 return nil, xerrors.Errorf("JSON decode error: %w", err) 94 } 95 96 severity := convertSeverity(specific.Severity) 97 for i, adv := range advisories { 98 advisories[i].Severity = severity 99 100 // Replace a git URL with a CocoaPods package name in a Swift vulnerability 101 // and store it as a CocoaPods vulnerability. 102 if adv.Ecosystem == vulnerability.Swift { 103 adv.Severity = severity 104 adv.Ecosystem = vulnerability.Cocoapods 105 for _, pkgName := range t.cocoaPodsSpecs[adv.PkgName] { 106 adv.PkgName = pkgName 107 advisories = append(advisories, adv) 108 } 109 } 110 } 111 112 return advisories, nil 113 } 114 115 func convertSeverity(severity string) types.Severity { 116 switch severity { 117 case "LOW": 118 return types.SeverityLow 119 case "MODERATE": 120 return types.SeverityMedium 121 case "HIGH": 122 return types.SeverityHigh 123 case "CRITICAL": 124 return types.SeverityCritical 125 default: 126 return types.SeverityUnknown 127 } 128 }