Skip to content

Commit

Permalink
output total finding information (praetorian-inc#44)
Browse files Browse the repository at this point in the history
* update finding types to refer to CWE id

* updated remote repository scanning functionality

* added basic dockerfile and readme instructions

* fix the broken tests

* properly clean up temporary directory when the remote scan fails

* output total finding information

* removed one test case

* line endings

* output finding information as json
  • Loading branch information
praetorian-thendrickson committed Sep 17, 2021
1 parent 120a1ef commit bbf8fa3
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 6 deletions.
16 changes: 15 additions & 1 deletion analyzers/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func FilterResults(unfilteredResults []util.Finding, parent_dir string) ([]util.

func OutputResults(results []util.Finding, success bool) error {
var stdOutPipe, outputFile *os.File
var outputColor = true

if util.Config.OutputPath != "" {
stdOutPipe = os.Stdout // keep backup of the real stdout
Expand All @@ -70,6 +71,15 @@ func OutputResults(results []util.Finding, success bool) error {
return err
}
os.Stdout = outputFile
outputColor = false
}

if util.Config.OutputJSON && success {
res, err := json.Marshal(results)
if err != nil {
return err
}
fmt.Println(string(res))
}

if util.Config.OutputJSON && success {
Expand All @@ -81,7 +91,7 @@ func OutputResults(results []util.Finding, success bool) error {
}

for _, finding := range results {
util.OutputFinding(finding)
util.OutputFinding(finding, outputColor)
}

// if packages were able to be scanned, print the correct output message
Expand All @@ -92,6 +102,8 @@ func OutputResults(results []util.Finding, success bool) error {

// if output was redirected for findings, change it back to the original stdout
if util.Config.OutputPath != "" {
// also generate the count of findings identified to the output file
util.OutputFindingMetadata(results, outputColor)
outputFile.Close()
os.Stdout = stdOutPipe // restoring the real stdout
}
Expand Down Expand Up @@ -201,6 +213,8 @@ func Scan(args []string) ([]util.Finding, error) {
if !(util.Config.OutputSarif || util.Config.OutputJSON) && success {
fmt.Println("\nRace Complete! Analysis took", scan_time, "and", util.FilesFound, "Go files were scanned (including imported packages)")
fmt.Printf("GoKart found %d potentially vulnerable functions\n", len(filteredResults))
// display information about all findings
util.OutputFindingMetadata(filteredResults, true)
}
os.Chdir(current_dir)

Expand Down
3 changes: 1 addition & 2 deletions cmd/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ func TestScanCommand(t *testing.T) {
moduledir string
}{
{[]string{"scan"}, "GoKart found 0 potentially vulnerable functions", ""},
{[]string{"scan", "-r", "https://github.com/Contrast-Security-OSS/go-test-bench"}, "GoKart found 8 potentially vulnerable functions", cur_dir + "/go-test-bench"},
{[]string{"scan", "-r", "https://github.com/praetorian-inc/gokart"}, "GoKart found 0 potentially vulnerable functions", cur_dir + "/gokart"},
{[]string{"scan", "-r", "github.com/praetorian-inc/gokart"}, "GoKart found 0 potentially vulnerable functions", cur_dir + "/gokart"},
{[]string{"scan", "--help"}, " -v, --verbose outputs full trace of taint analysis", ""},
}
for _, tt := range tests {
Expand Down
38 changes: 35 additions & 3 deletions util/finding.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,32 @@ func IsValidFinding(finding Finding) bool {
return true
}

func OutputFindingMetadata(results []Finding, outputColor bool) {
var ok bool
findingCounts := make(map[string]int)

for _, finding := range results {
_, ok = findingCounts[finding.Type]
if ok {
findingCounts[finding.Type] += 1
} else {
findingCounts[finding.Type] = 1
}
}

for findingType, count := range findingCounts {
if outputColor {
yellow := color.New(color.FgYellow).SprintFunc()
cyan := color.New(color.FgCyan).SprintFunc()
fmt.Printf("Identified %s potential %s\n", yellow(count), cyan(findingType))
} else {
fmt.Printf("Identified %d potential %s\n", count, findingType)
}
}
}

// prints out a finding
func OutputFinding(finding Finding) {
func OutputFinding(finding Finding, outputColor bool) {
if Config.OutputSarif {
SarifRecordFinding(finding.Type, finding.message, finding.Vulnerable_Function.SourceFilename,
finding.Vulnerable_Function.SourceLineNum)
Expand All @@ -83,7 +107,11 @@ func OutputFinding(finding Finding) {

sinkParentNoArgs := StripArguments(finding.Vulnerable_Function.ParentFunction)

fmt.Printf("\n(%s) %s\n\n", cyan(finding.Type), yellow(finding.message))
if outputColor {
fmt.Printf("\n(%s) %s\n\n", cyan(finding.Type), yellow(finding.message))
} else {
fmt.Printf("\n(%s) %s\n\n", finding.Type, finding.message)
}
fmt.Printf("%s:%d\nVulnerable Function: [ %s ]\n", finding.Vulnerable_Function.SourceFilename, finding.Vulnerable_Function.SourceLineNum, sinkParentNoArgs)
fmt.Printf(" %d:\t%s\n", finding.Vulnerable_Function.SourceLineNum-1, GrabSourceCode(finding.Vulnerable_Function.SourceFilename, finding.Vulnerable_Function.SourceLineNum-1))
fmt.Printf(" > %d:\t%s\n", finding.Vulnerable_Function.SourceLineNum, finding.Vulnerable_Function.SourceCode)
Expand All @@ -99,7 +127,11 @@ func OutputFinding(finding Finding) {
fmt.Printf(" %d:\t%s\n", source.SourceLineNum+1, GrabSourceCode(source.SourceFilename, source.SourceLineNum+1))

if Config.Verbose {
fmt.Print(green("\n############################### FULL TRACE ###############################\n"))
if outputColor {
fmt.Print(green("\n############################### FULL TRACE ###############################\n"))
} else {
fmt.Print("\n############################### FULL TRACE ###############################\n")
}
fmt.Printf("\nUntrusted Input Source:")
for _, source := range finding.Untrusted_Source {
fmt.Printf("%s:%d:\n[ %s ]\n>>>\t%s\n", source.SourceFilename,
Expand Down

0 comments on commit bbf8fa3

Please sign in to comment.