diff --git a/Gopkg.lock b/Gopkg.lock index f20f5bdb..c87f8d2f 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -28,8 +28,8 @@ [[projects]] name = "github.com/aws/aws-sdk-go" packages = ["aws","aws/awserr","aws/awsutil","aws/client","aws/client/metadata","aws/corehandlers","aws/credentials","aws/credentials/ec2rolecreds","aws/credentials/endpointcreds","aws/credentials/stscreds","aws/defaults","aws/ec2metadata","aws/endpoints","aws/request","aws/session","aws/signer/v4","internal/shareddefaults","private/protocol","private/protocol/query","private/protocol/query/queryutil","private/protocol/rest","private/protocol/restxml","private/protocol/xml/xmlutil","service/s3","service/sts"] - revision = "b69f447375c7fa0047ebcdd8ae5d585d5aac2f71" - version = "v1.10.51" + revision = "c652f9369083515c3ddf1fbaf6df68da2c101545" + version = "v1.12.1" [[projects]] name = "github.com/boltdb/bolt" @@ -106,8 +106,7 @@ [[projects]] name = "github.com/jmespath/go-jmespath" packages = ["."] - revision = "3433f3ea46d9f8019119e7dd41274e112a2359a9" - version = "0.2.2" + revision = "0b12d6b5" [[projects]] name = "github.com/jroimartin/gocui" @@ -119,7 +118,7 @@ branch = "master" name = "github.com/k0kubun/pp" packages = ["."] - revision = "d1532fc5d94ecdf2da29e24d7b99721f3287de4a" + revision = "e057ee7a28277be4d2af303443b6da377768181f" [[projects]] branch = "master" @@ -149,7 +148,7 @@ branch = "master" name = "github.com/kotakanbe/goval-dictionary" packages = ["config","db","db/rdb","log","models"] - revision = "a9de1f6e9126c5e75b46b39e4049624cde8c8bb4" + revision = "fd8ff5a6343912117d1b7db16fbd5fa1f4116c3a" [[projects]] branch = "master" @@ -245,19 +244,19 @@ branch = "master" name = "golang.org/x/crypto" packages = ["curve25519","ed25519","ed25519/internal/edwards25519","ssh","ssh/agent","ssh/terminal"] - revision = "847319b7fc94cab682988f93da778204da164588" + revision = "c84b36c635ad003a10f0c755dff5685ceef18c71" [[projects]] branch = "master" name = "golang.org/x/net" packages = ["context","idna","publicsuffix"] - revision = "0744d001aa8470aaa53df28d32e5ceeb8af9bd70" + revision = "0a9397675ba34b2845f758fe3cd68828369c6517" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix","windows"] - revision = "429f518978ab01db8bb6f44b66785088e7fba58b" + revision = "314a259e304ff91bd6985da2a7149bbf91237993" [[projects]] branch = "master" diff --git a/README.ja.md b/README.ja.md index caed4596..97a1ac65 100644 --- a/README.ja.md +++ b/README.ja.md @@ -1161,6 +1161,7 @@ report: [-cvss-over=7] [-diff] [-ignore-unscored-cves] + [-ignore-unfixed] [-to-email] [-to-slack] [-to-localfile] @@ -1235,6 +1236,8 @@ report: http://proxy-url:port (default: empty) -ignore-unscored-cves Don't report the unscored CVEs + -ignore-unfixed + Don't report the unfixed CVEs -lang string [en|ja] (default "en") -log-dir string diff --git a/README.md b/README.md index 609d18ba..94fcd42e 100644 --- a/README.md +++ b/README.md @@ -1174,6 +1174,7 @@ report: [-cvss-over=7] [-diff] [-ignore-unscored-cves] + [-ignore-unfixed] [-to-email] [-to-slack] [-to-localfile] @@ -1248,6 +1249,8 @@ report: http://proxy-url:port (default: empty) -ignore-unscored-cves Don't report the unscored CVEs + -ignore-unfixed + Don't report the unfixed CVEs -lang string [en|ja] (default "en") -log-dir string diff --git a/commands/report.go b/commands/report.go index 1e69b32e..a5cc74b7 100644 --- a/commands/report.go +++ b/commands/report.go @@ -44,7 +44,9 @@ type ReportCmd struct { cvssScoreOver float64 ignoreUnscoredCves bool - httpProxy string + ignoreUnfixed bool + + httpProxy string cveDBType string cveDBPath string @@ -107,6 +109,7 @@ func (*ReportCmd) Usage() string { [-cvss-over=7] [-diff] [-ignore-unscored-cves] + [-ignore-unfixed] [-to-email] [-to-slack] [-to-localfile] @@ -213,6 +216,12 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) { false, "Don't report the unscored CVEs") + f.BoolVar( + &p.ignoreUnfixed, + "ignore-unfixed", + false, + "Don't report the unfixed CVEs") + f.StringVar( &p.httpProxy, "http-proxy", @@ -312,6 +321,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{} c.Conf.OvalDBURL = p.ovalDBURL c.Conf.CvssScoreOver = p.cvssScoreOver c.Conf.IgnoreUnscoredCves = p.ignoreUnscoredCves + c.Conf.IgnoreUnfixed = p.ignoreUnfixed c.Conf.HTTPProxy = p.httpProxy c.Conf.FormatXML = p.formatXML diff --git a/config/config.go b/config/config.go index 03e3df55..15cf6e36 100644 --- a/config/config.go +++ b/config/config.go @@ -91,6 +91,7 @@ type Config struct { CvssScoreOver float64 IgnoreUnscoredCves bool + IgnoreUnfixed bool SSHNative bool ContainersOnly bool diff --git a/models/scanresults.go b/models/scanresults.go index 954ec8ed..c144d139 100644 --- a/models/scanresults.go +++ b/models/scanresults.go @@ -76,10 +76,8 @@ func (r ScanResult) FilterByCvssOver(over float64) ScanResult { } return false }) - - copiedScanResult := r - copiedScanResult.ScannedCves = filtered - return copiedScanResult + r.ScannedCves = filtered + return r } // FilterIgnoreCves is filter function. @@ -92,9 +90,24 @@ func (r ScanResult) FilterIgnoreCves(cveIDs []string) ScanResult { } return true }) - copiedScanResult := r - copiedScanResult.ScannedCves = filtered - return copiedScanResult + r.ScannedCves = filtered + return r +} + +// FilterUnfixed is filter function. +func (r ScanResult) FilterUnfixed() ScanResult { + if !config.Conf.IgnoreUnfixed { + return r + } + filtered := r.ScannedCves.Find(func(v VulnInfo) bool { + NotFixedAll := true + for _, p := range v.AffectedPackages { + NotFixedAll = NotFixedAll && p.NotFixedYet + } + return !NotFixedAll + }) + r.ScannedCves = filtered + return r } // ReportFileName returns the filename on localhost without extention diff --git a/models/scanresults_test.go b/models/scanresults_test.go index 9df1a52b..97ca4a10 100644 --- a/models/scanresults_test.go +++ b/models/scanresults_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + "github.com/future-architect/vuls/config" "github.com/k0kubun/pp" ) @@ -255,3 +256,83 @@ func TestFilterIgnoreCveIDs(t *testing.T) { } } } + +func TestFilterUnfixed(t *testing.T) { + var tests = []struct { + in ScanResult + out ScanResult + }{ + { + in: ScanResult{ + ScannedCves: VulnInfos{ + "CVE-2017-0001": { + CveID: "CVE-2017-0001", + AffectedPackages: PackageStatuses{ + { + Name: "a", + NotFixedYet: true, + }, + }, + }, + "CVE-2017-0002": { + CveID: "CVE-2017-0002", + AffectedPackages: PackageStatuses{ + { + Name: "b", + NotFixedYet: false, + }, + }, + }, + "CVE-2017-0003": { + CveID: "CVE-2017-0003", + AffectedPackages: PackageStatuses{ + { + Name: "c", + NotFixedYet: true, + }, + { + Name: "d", + NotFixedYet: false, + }, + }, + }, + }, + }, + out: ScanResult{ + ScannedCves: VulnInfos{ + "CVE-2017-0002": { + CveID: "CVE-2017-0002", + AffectedPackages: PackageStatuses{ + { + Name: "b", + NotFixedYet: false, + }, + }, + }, + "CVE-2017-0003": { + CveID: "CVE-2017-0003", + AffectedPackages: PackageStatuses{ + { + Name: "c", + NotFixedYet: true, + }, + { + Name: "d", + NotFixedYet: false, + }, + }, + }, + }, + }, + }, + } + for i, tt := range tests { + config.Conf.IgnoreUnfixed = true + actual := tt.in.FilterUnfixed() + if !reflect.DeepEqual(tt.out.ScannedCves, actual.ScannedCves) { + o := pp.Sprintf("%v", tt.out.ScannedCves) + a := pp.Sprintf("%v", actual.ScannedCves) + t.Errorf("[%d] expected: %v\n actual: %v\n", i, o, a) + } + } +} diff --git a/report/report.go b/report/report.go index edcad543..98caf8d7 100644 --- a/report/report.go +++ b/report/report.go @@ -81,6 +81,7 @@ func FillCveInfos(rs []models.ScanResult, dir string) ([]models.ScanResult, erro for _, r := range filled { r = r.FilterByCvssOver(c.Conf.CvssScoreOver) r = r.FilterIgnoreCves(c.Conf.Servers[r.ServerName].IgnoreCves) + r = r.FilterUnfixed() filtered = append(filtered, r) } return filtered, nil