-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from appknox/cicheck
Add cicheck command
- Loading branch information
Showing
7 changed files
with
173 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/appknox/appknox-go/helper" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// cicheckCmd represents the cicheck command | ||
var cicheckCmd = &cobra.Command{ | ||
Use: "cicheck", | ||
Short: "Check for vulnerabilities based on risk threshold.", | ||
Long: `List all the vulnerabilities with the risk threshold greater or equal than the provided and fail the command.`, | ||
Args: func(cmd *cobra.Command, args []string) error { | ||
if len(args) < 1 { | ||
return errors.New("file id is required") | ||
} | ||
return nil | ||
}, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
fileID, err := strconv.Atoi(args[0]) | ||
if err != nil { | ||
fmt.Fprintln(os.Stderr, err) | ||
os.Exit(1) | ||
} | ||
riskThreshold, _ := cmd.Flags().GetString("risk_threshold") | ||
riskThresholdLower := strings.ToLower(riskThreshold) | ||
var riskThresholdInt int | ||
switch riskThresholdStr := riskThresholdLower; riskThresholdStr { | ||
case "low": | ||
riskThresholdInt = 1 | ||
case "medium": | ||
riskThresholdInt = 2 | ||
case "high": | ||
riskThresholdInt = 3 | ||
case "critical": | ||
riskThresholdInt = 4 | ||
default: | ||
err := errors.New("valid risk threshold is required") | ||
fmt.Fprintln(os.Stderr, err) | ||
os.Exit(1) | ||
} | ||
helper.ProcessCiCheck(fileID, riskThresholdInt) | ||
}, | ||
} | ||
|
||
func init() { | ||
RootCmd.AddCommand(cicheckCmd) | ||
cicheckCmd.Flags().StringP( | ||
"risk_threshold", "r", "low", "Risk threshold to fail the command. Available options: low, medium, high") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package helper | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"os" | ||
"time" | ||
|
||
"github.com/appknox/appknox-go/appknox" | ||
"github.com/appknox/appknox-go/appknox/enums" | ||
"github.com/cheynewallace/tabby" | ||
"github.com/vbauerster/mpb/v4" | ||
"github.com/vbauerster/mpb/v4/decor" | ||
) | ||
|
||
// ProcessCiCheck takes the list of analyses and print it to CLI. | ||
func ProcessCiCheck(fileID, riskThreshold int) { | ||
ctx := context.Background() | ||
client := getClient() | ||
var staticScanProgess int | ||
start := time.Now() | ||
p := mpb.New( | ||
mpb.WithWidth(60), | ||
mpb.WithRefreshRate(180*time.Millisecond), | ||
mpb.WithOutput(os.Stderr), | ||
) | ||
name := "Static Scan Progress: " | ||
bar := p.AddBar(100, mpb.BarStyle("[=>-|"), | ||
mpb.PrependDecorators( | ||
decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}), | ||
decor.Percentage(), | ||
), | ||
mpb.AppendDecorators( | ||
decor.Name("] "), | ||
), | ||
) | ||
|
||
for staticScanProgess < 100 { | ||
file, _, err := client.Files.GetByID(ctx, fileID) | ||
if err != nil { | ||
fmt.Fprintln(os.Stderr, err) | ||
os.Exit(1) | ||
} | ||
staticScanProgess = file.StaticScanProgress | ||
bar.SetCurrent(int64(staticScanProgess), time.Since(start)) | ||
if time.Since(start) > 15*time.Minute { | ||
err := errors.New("Request timed out") | ||
fmt.Fprintln(os.Stderr, err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
_, analysisResponse, err := client.Analyses.ListByFile(ctx, fileID, nil) | ||
analysisCount := analysisResponse.GetCount() | ||
options := &appknox.AnalysisListOptions{ | ||
ListOptions: appknox.ListOptions{ | ||
Limit: analysisCount}, | ||
} | ||
finalAnalyses, _, err := client.Analyses.ListByFile(ctx, fileID, options) | ||
if err != nil { | ||
fmt.Fprintln(os.Stderr, err) | ||
os.Exit(1) | ||
} | ||
var foundVulnerability bool | ||
t := tabby.New() | ||
t.AddHeader( | ||
"ID", "RISK", "CVSS-VECTOR", | ||
"CVSS-BASE", "VULNERABILITY-ID", | ||
"VULNERABILITY-NAME") | ||
for i := 0; i < len(finalAnalyses); i++ { | ||
if int(finalAnalyses[i].Risk) >= riskThreshold { | ||
foundVulnerability = true | ||
vulnerabilityID := finalAnalyses[i].VulnerabilityID | ||
vulnerability, _, err := client.Vulnerabilities.GetByID(ctx, vulnerabilityID) | ||
if err != nil { | ||
fmt.Fprintln(os.Stderr, err) | ||
os.Exit(1) | ||
} | ||
t.AddLine( | ||
finalAnalyses[i].ID, | ||
finalAnalyses[i].Risk, | ||
finalAnalyses[i].CvssVector, | ||
finalAnalyses[i].CvssBase, | ||
vulnerabilityID, | ||
vulnerability.Name, | ||
) | ||
} | ||
} | ||
if foundVulnerability { | ||
fmt.Println( | ||
"Found vulnerabilities with risk threshold greater or equal than the provided:", enums.RiskType(riskThreshold)) | ||
fmt.Println("") | ||
t.Print() | ||
fmt.Println("") | ||
os.Exit(1) | ||
} else { | ||
fmt.Println( | ||
"No vulnerabilities found with risk threshold greater or equal than the provided:", enums.RiskType(riskThreshold)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters