Skip to content
This repository was archived by the owner on Nov 26, 2024. It is now read-only.

Commit e1b3849

Browse files
authored
Merge pull request #3 from intercloud/cache-calls-nvd
Cache calls to NVD database
2 parents 2ba760d + d2ec6b6 commit e1b3849

8 files changed

Lines changed: 101 additions & 13 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ You can pass *-verbose* option on command line to print vulnerability report, ev
3636
3737
You can set *-strict* flag on command line so that vulnerabilities without version are considered matching vulnerability. In this case, you should check vulnerability manually and disable it in configuration file if necessary.
3838
39+
You can pass more than one binary on command line. In this case, there will be cache on calls to NVD database.
40+
3941
## Configuration
4042
4143
You can pass configuration on command line with `-config` option:

go.mod

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,13 @@ module github.com/intercloud/gobinsec
22

33
go 1.17
44

5-
require gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
5+
require (
6+
github.com/fatih/color v1.13.0
7+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
8+
)
9+
10+
require (
11+
github.com/mattn/go-colorable v0.1.9 // indirect
12+
github.com/mattn/go-isatty v0.0.14 // indirect
13+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
14+
)

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
2+
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
3+
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
4+
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
5+
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
6+
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
7+
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
8+
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
9+
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
10+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
11+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
112
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
213
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
314
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=

gobinsec/binary.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,12 @@ func LoadVulnerabilities(dependencies chan *Dependency, wg *sync.WaitGroup) {
105105
// Report prints a report on terminal
106106
// nolint:gocyclo // this is life
107107
func (b *Binary) Report(verbose bool) {
108-
fmt.Printf("binary: '%s'\n", filepath.Base(b.Path))
109-
fmt.Printf("vulnerable: %t\n", b.Vulnerable)
108+
fmt.Printf("%s: ",filepath.Base(b.Path))
109+
if (b.Vulnerable) {
110+
ColorRed.Println("VULNERABLE")
111+
} else {
112+
ColorGreen.Println("OK")
113+
}
110114
if len(b.Dependencies) > 0 && (b.Vulnerable || verbose) {
111115
fmt.Println("dependencies:")
112116
for _, dependency := range b.Dependencies {

gobinsec/cache.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package gobinsec
2+
3+
import (
4+
"sync"
5+
)
6+
7+
type VulnerabilityCache map[string][]Vulnerability
8+
9+
var lock sync.RWMutex
10+
var cache = NewVulnerabilityCache()
11+
12+
func NewVulnerabilityCache() *VulnerabilityCache {
13+
cache := make(VulnerabilityCache)
14+
return &cache
15+
}
16+
17+
func (dc *VulnerabilityCache) Get(d *Dependency) []Vulnerability {
18+
key := d.Key()
19+
lock.RLock()
20+
defer lock.RUnlock()
21+
vulnerabilities, ok := (*dc)[key]
22+
if ok {
23+
return vulnerabilities
24+
}
25+
return nil
26+
}
27+
28+
func (dc *VulnerabilityCache) Put(d *Dependency, v []Vulnerability) {
29+
key := d.Key()
30+
if v == nil {
31+
v = make([]Vulnerability, 0)
32+
}
33+
lock.Lock()
34+
defer lock.Unlock()
35+
(*dc)[key] = v
36+
}

gobinsec/color.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package gobinsec
2+
3+
import "github.com/fatih/color"
4+
5+
var (
6+
ColorRed = color.New(color.FgRed).Add(color.Bold)
7+
ColorGreen = color.New(color.FgGreen).Add(color.Bold)
8+
)

gobinsec/dependency.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ func NewDependency(name, version string) (*Dependency, error) {
3131

3232
// Vulnerabilities return list of vulnerabilities for given dependency
3333
func (d *Dependency) LoadVulnerabilities() error {
34+
vulnerabilities := cache.Get(d)
35+
if vulnerabilities != nil {
36+
d.Vulnerabilities = vulnerabilities
37+
return nil
38+
}
3439
url := URL + d.Name
3540
if config.APIKey != "" {
3641
url += "&apiKey=" + config.APIKey
@@ -58,5 +63,11 @@ func (d *Dependency) LoadVulnerabilities() error {
5863
}
5964
d.Vulnerabilities = append(d.Vulnerabilities, *vulnerability)
6065
}
66+
cache.Put(d, d.Vulnerabilities)
6167
return nil
6268
}
69+
70+
// Key returns a key as a string for caching
71+
func (d *Dependency) Key() string {
72+
return d.Name
73+
}

main.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,29 @@ func main() {
2525
fmt.Println(Version)
2626
os.Exit(0)
2727
}
28-
if len(flag.Args()) != 1 {
29-
println("ERROR you must pass one binary to analyze")
28+
if len(flag.Args()) < 1 {
29+
println("ERROR you must pass binary/ies to analyze on command line")
3030
os.Exit(CodeError)
3131
}
3232
if err := gobinsec.LoadConfig(*config, *strict); err != nil {
33-
println(fmt.Sprintf("ERROR loading configuration: %v", err))
33+
println(fmt.Sprintf("ERROR %v", err))
3434
os.Exit(CodeError)
3535
}
36-
path := flag.Args()[0]
37-
binary, err := gobinsec.NewBinary(path)
38-
if err != nil {
39-
println(fmt.Sprintf("ERROR analyzing %s: %v", path, err))
40-
os.Exit(CodeError)
36+
issue := false
37+
for _, path := range flag.Args() {
38+
binary, err := gobinsec.NewBinary(path)
39+
if err != nil {
40+
gobinsec.ColorRed.Print("ERROR")
41+
fmt.Printf(" analyzing %s: %v\n", path, err)
42+
issue = true
43+
} else {
44+
binary.Report(*verbose)
45+
if binary.Vulnerable {
46+
issue = true
47+
}
48+
}
4149
}
42-
binary.Report(*verbose)
43-
if binary.Vulnerable {
50+
if issue {
4451
os.Exit(CodeVulnerable)
4552
}
4653
}

0 commit comments

Comments
 (0)