Skip to content

Commit

Permalink
Merge pull request #48 from cerberauth/improve-output
Browse files Browse the repository at this point in the history
feat: improve command output display
  • Loading branch information
emmanuelgautier authored Feb 27, 2024
2 parents 96c83c4 + 75d616c commit d2ce09a
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 22 deletions.
53 changes: 46 additions & 7 deletions cmd/scan/curl.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ package scan
import (
"log"
"net/http"
"os"
"strings"

"github.com/cerberauth/vulnapi/scan"
"github.com/common-nighthawk/go-figure"
"github.com/fatih/color"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
)

Expand All @@ -24,6 +28,9 @@ func NewCURLScanCmd() (scanCmd *cobra.Command) {
FParseErrWhitelist: cobra.FParseErrWhitelist{
UnknownFlags: true,
},
PreRun: func(cmd *cobra.Command, args []string) {
figure.NewColorFigure("VulnAPI", "", "cyan", true).Print()
},
Run: func(cmd *cobra.Command, args []string) {
url = args[0]

Expand All @@ -47,20 +54,52 @@ func NewCURLScanCmd() (scanCmd *cobra.Command) {
log.Fatal(err)
}

rpr, _, err := scan.WithAllVulnsScans().WithAllBestPracticesScans().Execute()
reporter, _, err := scan.WithAllVulnsScans().WithAllBestPracticesScans().Execute()
if err != nil {
log.Fatal(err)
}

for _, r := range rpr.GetVulnerabilityReports() {
log.Println(r)
var outputColor *color.Color
var outputMessage string
var outputStream *os.File
if !reporter.HasVulnerability() {
outputColor = color.New(color.FgGreen)
outputMessage = "Congratulations! No issues were found."
outputStream = os.Stdout
} else if reporter.HasHighRiskSeverityVulnerability() {
outputColor = color.New(color.FgRed)
outputMessage = "Warning: Critical vulnerabilities detected!"
outputStream = os.Stderr
} else {
outputColor = color.New(color.FgYellow)
outputMessage = "Advice: There are some low-risk issues. It's advised to take a look."
outputStream = os.Stderr
}

if !rpr.HasVulnerability() {
log.Println("Congratulations! No vulnerability has been discovered!")
} else {
log.Fatalln("There is one or more vulnerabilies you should know.")
table := tablewriter.NewWriter(outputStream)
table.SetHeader([]string{"Risk Level", "Vulnerability", "Description"})

for _, v := range reporter.GetVulnerabilityReports() {
var lineColor int
if v.IsLowRiskSeverity() {
lineColor = tablewriter.BgBlueColor
} else if v.IsMediumRiskSeverity() {
lineColor = tablewriter.FgYellowColor
} else if v.IsHighRiskSeverity() {
lineColor = tablewriter.FgRedColor
}

table.Rich(
[]string{v.SeverityLevelString(), v.Name, v.Description},
[]tablewriter.Colors{
{tablewriter.Bold, lineColor},
{tablewriter.Normal, lineColor},
{tablewriter.Normal, tablewriter.FgWhiteColor}},
)
}

table.Render()
outputColor.Fprintln(outputStream, outputMessage)
},
}

Expand Down
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ go 1.22

require (
github.com/brianvoe/gofakeit/v6 v6.28.0
github.com/brianvoe/gofakeit/v7 v7.0.1
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be
github.com/fatih/color v1.16.0
github.com/getkin/kin-openapi v0.120.0
github.com/golang-jwt/jwt/v5 v5.2.0
github.com/jarcoal/httpmock v1.3.1
github.com/olekukonko/tablewriter v0.0.5
github.com/spf13/cobra v1.8.0
github.com/std-uritemplate/std-uritemplate/go v0.0.52
github.com/stretchr/testify v1.8.4
Expand All @@ -21,9 +23,13 @@ require (
github.com/invopop/yaml v0.2.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
18 changes: 17 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4=
github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs=
github.com/brianvoe/gofakeit/v7 v7.0.1/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA=
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ=
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg=
github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
Expand Down Expand Up @@ -33,10 +36,19 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=
github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -58,6 +70,10 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
26 changes: 14 additions & 12 deletions report/vuln.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package report

import "fmt"
import (
"fmt"
)

type VulnerabilityReport struct {
SeverityLevel float64 // https://nvd.nist.gov/vuln-metrics/cvss
Expand All @@ -22,19 +24,19 @@ func (vr *VulnerabilityReport) IsHighRiskSeverity() bool {
}

func (vr *VulnerabilityReport) String() string {
return fmt.Sprintf("[%s][%s] %s: %s", severyLevelString(vr.SeverityLevel), vr.Name, vr.Url, vr.Description)
return fmt.Sprintf("[%s][%s] %s: %s", vr.SeverityLevelString(), vr.Name, vr.Url, vr.Description)
}

func severyLevelString(severityLevel float64) string {
if severityLevel >= 9 {
return "critical"
} else if severityLevel < 9 && severityLevel >= 7 {
return "high"
} else if severityLevel < 7 && severityLevel >= 4 {
return "medium"
} else if severityLevel < 4 && severityLevel >= 0.1 {
return "low"
func (vr *VulnerabilityReport) SeverityLevelString() string {
if vr.SeverityLevel >= 9 {
return "Critical"
} else if vr.SeverityLevel < 9 && vr.SeverityLevel >= 7 {
return "High"
} else if vr.SeverityLevel < 7 && vr.SeverityLevel >= 4 {
return "Medium"
} else if vr.SeverityLevel < 4 && vr.SeverityLevel >= 0.1 {
return "Low"
} else {
return "none"
return "None"
}
}
25 changes: 24 additions & 1 deletion report/vuln_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,29 @@ func TestVulnerabilityReport_String(t *testing.T) {
Description: "This is a test vulnerability",
Url: "https://example.com/vulnerability",
}
expected := "[high][Test Vulnerability] https://example.com/vulnerability: This is a test vulnerability"
expected := "[High][Test Vulnerability] https://example.com/vulnerability: This is a test vulnerability"
assert.Equal(t, expected, vr.String())
}
func TestVulnerabilityReport_SeverityLevelString(t *testing.T) {
vr := &report.VulnerabilityReport{}

// Test case for severity level >= 9
vr.SeverityLevel = 9.5
assert.Equal(t, "Critical", vr.SeverityLevelString())

// Test case for severity level < 9 and >= 7
vr.SeverityLevel = 7.5
assert.Equal(t, "High", vr.SeverityLevelString())

// Test case for severity level < 7 and >= 4
vr.SeverityLevel = 4.5
assert.Equal(t, "Medium", vr.SeverityLevelString())

// Test case for severity level < 4 and >= 0.1
vr.SeverityLevel = 0.5
assert.Equal(t, "Low", vr.SeverityLevelString())

// Test case for severity level < 0.1
vr.SeverityLevel = 0.05
assert.Equal(t, "None", vr.SeverityLevelString())
}

0 comments on commit d2ce09a

Please sign in to comment.