Skip to content

Commit d2ce09a

Browse files
Merge pull request #48 from cerberauth/improve-output
feat: improve command output display
2 parents 96c83c4 + 75d616c commit d2ce09a

File tree

5 files changed

+108
-22
lines changed

5 files changed

+108
-22
lines changed

cmd/scan/curl.go

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ package scan
33
import (
44
"log"
55
"net/http"
6+
"os"
67
"strings"
78

89
"github.com/cerberauth/vulnapi/scan"
10+
"github.com/common-nighthawk/go-figure"
11+
"github.com/fatih/color"
12+
"github.com/olekukonko/tablewriter"
913
"github.com/spf13/cobra"
1014
)
1115

@@ -24,6 +28,9 @@ func NewCURLScanCmd() (scanCmd *cobra.Command) {
2428
FParseErrWhitelist: cobra.FParseErrWhitelist{
2529
UnknownFlags: true,
2630
},
31+
PreRun: func(cmd *cobra.Command, args []string) {
32+
figure.NewColorFigure("VulnAPI", "", "cyan", true).Print()
33+
},
2734
Run: func(cmd *cobra.Command, args []string) {
2835
url = args[0]
2936

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

50-
rpr, _, err := scan.WithAllVulnsScans().WithAllBestPracticesScans().Execute()
57+
reporter, _, err := scan.WithAllVulnsScans().WithAllBestPracticesScans().Execute()
5158
if err != nil {
5259
log.Fatal(err)
5360
}
5461

55-
for _, r := range rpr.GetVulnerabilityReports() {
56-
log.Println(r)
62+
var outputColor *color.Color
63+
var outputMessage string
64+
var outputStream *os.File
65+
if !reporter.HasVulnerability() {
66+
outputColor = color.New(color.FgGreen)
67+
outputMessage = "Congratulations! No issues were found."
68+
outputStream = os.Stdout
69+
} else if reporter.HasHighRiskSeverityVulnerability() {
70+
outputColor = color.New(color.FgRed)
71+
outputMessage = "Warning: Critical vulnerabilities detected!"
72+
outputStream = os.Stderr
73+
} else {
74+
outputColor = color.New(color.FgYellow)
75+
outputMessage = "Advice: There are some low-risk issues. It's advised to take a look."
76+
outputStream = os.Stderr
5777
}
5878

59-
if !rpr.HasVulnerability() {
60-
log.Println("Congratulations! No vulnerability has been discovered!")
61-
} else {
62-
log.Fatalln("There is one or more vulnerabilies you should know.")
79+
table := tablewriter.NewWriter(outputStream)
80+
table.SetHeader([]string{"Risk Level", "Vulnerability", "Description"})
81+
82+
for _, v := range reporter.GetVulnerabilityReports() {
83+
var lineColor int
84+
if v.IsLowRiskSeverity() {
85+
lineColor = tablewriter.BgBlueColor
86+
} else if v.IsMediumRiskSeverity() {
87+
lineColor = tablewriter.FgYellowColor
88+
} else if v.IsHighRiskSeverity() {
89+
lineColor = tablewriter.FgRedColor
90+
}
91+
92+
table.Rich(
93+
[]string{v.SeverityLevelString(), v.Name, v.Description},
94+
[]tablewriter.Colors{
95+
{tablewriter.Bold, lineColor},
96+
{tablewriter.Normal, lineColor},
97+
{tablewriter.Normal, tablewriter.FgWhiteColor}},
98+
)
6399
}
100+
101+
table.Render()
102+
outputColor.Fprintln(outputStream, outputMessage)
64103
},
65104
}
66105

go.mod

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ go 1.22
44

55
require (
66
github.com/brianvoe/gofakeit/v6 v6.28.0
7-
github.com/brianvoe/gofakeit/v7 v7.0.1
7+
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be
8+
github.com/fatih/color v1.16.0
89
github.com/getkin/kin-openapi v0.120.0
910
github.com/golang-jwt/jwt/v5 v5.2.0
1011
github.com/jarcoal/httpmock v1.3.1
12+
github.com/olekukonko/tablewriter v0.0.5
1113
github.com/spf13/cobra v1.8.0
1214
github.com/std-uritemplate/std-uritemplate/go v0.0.52
1315
github.com/stretchr/testify v1.8.4
@@ -21,9 +23,13 @@ require (
2123
github.com/invopop/yaml v0.2.0 // indirect
2224
github.com/josharian/intern v1.0.0 // indirect
2325
github.com/mailru/easyjson v0.7.7 // indirect
26+
github.com/mattn/go-colorable v0.1.13 // indirect
27+
github.com/mattn/go-isatty v0.0.20 // indirect
28+
github.com/mattn/go-runewidth v0.0.9 // indirect
2429
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
2530
github.com/perimeterx/marshmallow v1.1.5 // indirect
2631
github.com/pmezard/go-difflib v1.0.0 // indirect
2732
github.com/spf13/pflag v1.0.5 // indirect
33+
golang.org/x/sys v0.14.0 // indirect
2834
gopkg.in/yaml.v3 v3.0.1 // indirect
2935
)

go.sum

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4=
22
github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs=
3-
github.com/brianvoe/gofakeit/v7 v7.0.1/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA=
3+
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ=
4+
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
45
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
56
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
67
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
78
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
89
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10+
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
11+
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
912
github.com/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg=
1013
github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw=
1114
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
@@ -33,10 +36,19 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
3336
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
3437
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
3538
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
39+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
40+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
41+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
42+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
43+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
44+
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
45+
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
3646
github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=
3747
github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
3848
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
3949
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
50+
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
51+
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
4052
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
4153
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
4254
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -58,6 +70,10 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
5870
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
5971
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
6072
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
73+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
74+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
75+
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
76+
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
6177
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6278
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
6379
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

report/vuln.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package report
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
)
46

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

2426
func (vr *VulnerabilityReport) String() string {
25-
return fmt.Sprintf("[%s][%s] %s: %s", severyLevelString(vr.SeverityLevel), vr.Name, vr.Url, vr.Description)
27+
return fmt.Sprintf("[%s][%s] %s: %s", vr.SeverityLevelString(), vr.Name, vr.Url, vr.Description)
2628
}
2729

28-
func severyLevelString(severityLevel float64) string {
29-
if severityLevel >= 9 {
30-
return "critical"
31-
} else if severityLevel < 9 && severityLevel >= 7 {
32-
return "high"
33-
} else if severityLevel < 7 && severityLevel >= 4 {
34-
return "medium"
35-
} else if severityLevel < 4 && severityLevel >= 0.1 {
36-
return "low"
30+
func (vr *VulnerabilityReport) SeverityLevelString() string {
31+
if vr.SeverityLevel >= 9 {
32+
return "Critical"
33+
} else if vr.SeverityLevel < 9 && vr.SeverityLevel >= 7 {
34+
return "High"
35+
} else if vr.SeverityLevel < 7 && vr.SeverityLevel >= 4 {
36+
return "Medium"
37+
} else if vr.SeverityLevel < 4 && vr.SeverityLevel >= 0.1 {
38+
return "Low"
3739
} else {
38-
return "none"
40+
return "None"
3941
}
4042
}

report/vuln_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,29 @@ func TestVulnerabilityReport_String(t *testing.T) {
2929
Description: "This is a test vulnerability",
3030
Url: "https://example.com/vulnerability",
3131
}
32-
expected := "[high][Test Vulnerability] https://example.com/vulnerability: This is a test vulnerability"
32+
expected := "[High][Test Vulnerability] https://example.com/vulnerability: This is a test vulnerability"
3333
assert.Equal(t, expected, vr.String())
3434
}
35+
func TestVulnerabilityReport_SeverityLevelString(t *testing.T) {
36+
vr := &report.VulnerabilityReport{}
37+
38+
// Test case for severity level >= 9
39+
vr.SeverityLevel = 9.5
40+
assert.Equal(t, "Critical", vr.SeverityLevelString())
41+
42+
// Test case for severity level < 9 and >= 7
43+
vr.SeverityLevel = 7.5
44+
assert.Equal(t, "High", vr.SeverityLevelString())
45+
46+
// Test case for severity level < 7 and >= 4
47+
vr.SeverityLevel = 4.5
48+
assert.Equal(t, "Medium", vr.SeverityLevelString())
49+
50+
// Test case for severity level < 4 and >= 0.1
51+
vr.SeverityLevel = 0.5
52+
assert.Equal(t, "Low", vr.SeverityLevelString())
53+
54+
// Test case for severity level < 0.1
55+
vr.SeverityLevel = 0.05
56+
assert.Equal(t, "None", vr.SeverityLevelString())
57+
}

0 commit comments

Comments
 (0)