forked from quay/claircore
-
Notifications
You must be signed in to change notification settings - Fork 0
/
matcher.go
96 lines (79 loc) · 2.42 KB
/
matcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package ruby
import (
"context"
"fmt"
"net/url"
"github.com/quay/zlog"
"github.com/quay/claircore"
"github.com/quay/claircore/libvuln/driver"
)
var _ driver.Matcher = (*Matcher)(nil)
// Matcher attempts to correlate discovered ruby packages with reported
// vulnerabilities.
type Matcher struct{}
// Name implements driver.Matcher.
func (*Matcher) Name() string { return "ruby-gem" }
// Filter implements driver.Matcher.
func (*Matcher) Filter(record *claircore.IndexRecord) bool {
return record.Repository != nil && record.Repository.Name == repository
}
// Query implements driver.Matcher.
func (*Matcher) Query() []driver.MatchConstraint {
return []driver.MatchConstraint{driver.RepositoryName}
}
// Vulnerable implements driver.Matcher.
func (*Matcher) Vulnerable(ctx context.Context, record *claircore.IndexRecord, vuln *claircore.Vulnerability) (bool, error) {
if vuln.FixedInVersion == "" {
return true, nil
}
decodedVersions, err := url.ParseQuery(vuln.FixedInVersion)
if err != nil {
return false, err
}
// Check for missing upper version
if !decodedVersions.Has("fixed") && !decodedVersions.Has("lastAffected") {
return false, fmt.Errorf("ruby: missing upper version")
}
upperVersion := decodedVersions.Get("fixed")
if upperVersion == "" {
upperVersion = decodedVersions.Get("lastAffected")
}
rv, err := NewVersion(record.Package.Version)
if err != nil {
zlog.Warn(ctx).
Str("package", record.Package.Name).
Str("version", record.Package.Version).
Msg("unable to parse ruby package version")
return false, err
}
uv, err := NewVersion(upperVersion)
if err != nil {
zlog.Warn(ctx).
Str("vulnerability", vuln.Name).
Str("package", vuln.Package.Name).
Str("version", upperVersion).
Msg("unable to parse ruby vulnerability 'fixed version' or 'last affected'")
return false, err
}
switch {
case decodedVersions.Has("fixed") && rv.Compare(uv) >= 0:
return false, nil
case decodedVersions.Has("lastAffected") && rv.Compare(uv) > 0:
return false, nil
case decodedVersions.Has("introduced"):
introduced := decodedVersions.Get("introduced")
iv, err := NewVersion(introduced)
if err != nil {
zlog.Warn(ctx).
Str("vulnerability", vuln.Name).
Str("package", vuln.Package.Name).
Str("version", introduced).
Msg("unable to parse ruby vulnerability 'introduced version'")
return false, err
}
if rv.Compare(iv) < 0 {
return false, nil
}
}
return true, nil
}