github.com/quay/claircore@v1.5.28/java/matcher.go (about) 1 package java 2 3 import ( 4 "context" 5 "github.com/quay/claircore" 6 "github.com/quay/claircore/libvuln/driver" 7 "github.com/quay/zlog" 8 "net/url" 9 ) 10 11 // Matcher matches discovered Java Maven packages against advisories provided via OSV. 12 type Matcher struct{} 13 14 var ( 15 _ driver.Matcher = (*Matcher)(nil) 16 ) 17 18 // Name implements driver.Matcher. 19 func (*Matcher) Name() string { return "java-maven" } 20 21 func (*Matcher) Filter(r *claircore.IndexRecord) bool { 22 return r.Repository != nil && 23 r.Repository.Name == Repository.Name 24 } 25 26 // Query implements driver.Matcher. 27 func (*Matcher) Query() []driver.MatchConstraint { 28 return []driver.MatchConstraint{driver.RepositoryName} 29 } 30 31 func (*Matcher) Vulnerable(ctx context.Context, record *claircore.IndexRecord, vuln *claircore.Vulnerability) (bool, error) { 32 // TODO(ross): This is a common pattern for OSV vulnerabilities. This should be moved into 33 // a common place for all OSV vulnerability matchers. 34 35 if vuln.FixedInVersion == "" { 36 return true, nil 37 } 38 39 // Parse the package first. If it cannot be parsed, it cannot properly be analyzed for vulnerabilities. 40 rv, err := parseMavenVersion(record.Package.Version) 41 if err != nil { 42 return false, err 43 } 44 45 decodedVersions, err := url.ParseQuery(vuln.FixedInVersion) 46 if err != nil { 47 return false, err 48 } 49 50 introduced := decodedVersions.Get("introduced") 51 // If there is an introduced version, check if the package's version is lower. 52 if introduced != "" { 53 iv, err := parseMavenVersion(introduced) 54 if err != nil { 55 zlog.Warn(ctx). 56 Str("package", vuln.Package.Name). 57 Str("version", introduced). 58 Msg("unable to parse maven introduced version") 59 return false, err 60 } 61 // If the package's version is less than the introduced version, it's not vulnerable. 62 if rv.Compare(iv) < 0 { 63 return false, nil 64 } 65 } 66 67 fixedVersion := decodedVersions.Get("fixed") 68 lastAffected := decodedVersions.Get("lastAffected") 69 switch { 70 case fixedVersion != "": 71 fv, err := parseMavenVersion(fixedVersion) 72 if err != nil { 73 zlog.Warn(ctx). 74 Str("package", vuln.Package.Name). 75 Str("version", fixedVersion). 76 Msg("unable to parse maven fixed version") 77 return false, err 78 } 79 // The package is affected if its version is less than the fixed version. 80 return rv.Compare(fv) < 0, nil 81 case lastAffected != "": 82 la, err := parseMavenVersion(lastAffected) 83 if err != nil { 84 zlog.Warn(ctx). 85 Str("package", vuln.Package.Name). 86 Str("version", lastAffected). 87 Msg("unable to parse maven last_affected version") 88 return false, err 89 } 90 // The package is affected if its version is less than or equal to the last affected version. 91 return rv.Compare(la) <= 0, nil 92 } 93 94 // Just say the package is vulnerable, by default. 95 return true, nil 96 }