Skip to content
This repository was archived by the owner on Nov 26, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ You can pass *-verbose* option on command line to print vulnerability report, ev

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.

You can pass more than one binary on command line. In this case, there will be cache on calls to NVD database.

## Configuration

You can pass configuration on command line with `-config` option:
Expand Down
11 changes: 10 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,13 @@ module github.com/intercloud/gobinsec

go 1.17

require gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
require (
github.com/fatih/color v1.13.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)

require (
github.com/mattn/go-colorable v0.1.9 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
Expand Down
8 changes: 6 additions & 2 deletions gobinsec/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,12 @@ func LoadVulnerabilities(dependencies chan *Dependency, wg *sync.WaitGroup) {
// Report prints a report on terminal
// nolint:gocyclo // this is life
func (b *Binary) Report(verbose bool) {
fmt.Printf("binary: '%s'\n", filepath.Base(b.Path))
fmt.Printf("vulnerable: %t\n", b.Vulnerable)
fmt.Printf("%s: ",filepath.Base(b.Path))
if (b.Vulnerable) {
ColorRed.Println("VULNERABLE")
} else {
ColorGreen.Println("OK")
}
if len(b.Dependencies) > 0 && (b.Vulnerable || verbose) {
fmt.Println("dependencies:")
for _, dependency := range b.Dependencies {
Expand Down
36 changes: 36 additions & 0 deletions gobinsec/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package gobinsec

import (
"sync"
)

type VulnerabilityCache map[string][]Vulnerability

var lock sync.RWMutex
var cache = NewVulnerabilityCache()

func NewVulnerabilityCache() *VulnerabilityCache {
cache := make(VulnerabilityCache)
return &cache
}

func (dc *VulnerabilityCache) Get(d *Dependency) []Vulnerability {
key := d.Key()
lock.RLock()
defer lock.RUnlock()
vulnerabilities, ok := (*dc)[key]
if ok {
return vulnerabilities
}
return nil
}

func (dc *VulnerabilityCache) Put(d *Dependency, v []Vulnerability) {
key := d.Key()
if v == nil {
v = make([]Vulnerability, 0)
}
lock.Lock()
defer lock.Unlock()
(*dc)[key] = v
}
8 changes: 8 additions & 0 deletions gobinsec/color.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package gobinsec

import "github.com/fatih/color"

var (
ColorRed = color.New(color.FgRed).Add(color.Bold)
ColorGreen = color.New(color.FgGreen).Add(color.Bold)
)
11 changes: 11 additions & 0 deletions gobinsec/dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ func NewDependency(name, version string) (*Dependency, error) {

// Vulnerabilities return list of vulnerabilities for given dependency
func (d *Dependency) LoadVulnerabilities() error {
vulnerabilities := cache.Get(d)
if vulnerabilities != nil {
d.Vulnerabilities = vulnerabilities
return nil
}
url := URL + d.Name
if config.APIKey != "" {
url += "&apiKey=" + config.APIKey
Expand Down Expand Up @@ -58,5 +63,11 @@ func (d *Dependency) LoadVulnerabilities() error {
}
d.Vulnerabilities = append(d.Vulnerabilities, *vulnerability)
}
cache.Put(d, d.Vulnerabilities)
return nil
}

// Key returns a key as a string for caching
func (d *Dependency) Key() string {
return d.Name
}
27 changes: 17 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,29 @@ func main() {
fmt.Println(Version)
os.Exit(0)
}
if len(flag.Args()) != 1 {
println("ERROR you must pass one binary to analyze")
if len(flag.Args()) < 1 {
println("ERROR you must pass binary/ies to analyze on command line")
os.Exit(CodeError)
}
if err := gobinsec.LoadConfig(*config, *strict); err != nil {
println(fmt.Sprintf("ERROR loading configuration: %v", err))
println(fmt.Sprintf("ERROR %v", err))
os.Exit(CodeError)
}
path := flag.Args()[0]
binary, err := gobinsec.NewBinary(path)
if err != nil {
println(fmt.Sprintf("ERROR analyzing %s: %v", path, err))
os.Exit(CodeError)
issue := false
for _, path := range flag.Args() {
binary, err := gobinsec.NewBinary(path)
if err != nil {
gobinsec.ColorRed.Print("ERROR")
fmt.Printf(" analyzing %s: %v\n", path, err)
issue = true
} else {
binary.Report(*verbose)
if binary.Vulnerable {
issue = true
}
}
}
binary.Report(*verbose)
if binary.Vulnerable {
if issue {
os.Exit(CodeVulnerable)
}
}