-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Let some people know they can try out newer versions, if we know they aren't bad! #225
base: main
Are you sure you want to change the base?
Changes from all commits
6a5ca1d
26acba3
3c452f5
2d6749e
a514a96
bd7f252
9feac53
b07433a
453613b
45979ee
af2d3f2
e9e94b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,7 @@ require ( | |
github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353 // indirect | ||
github.com/shopspring/decimal v1.2.0 | ||
github.com/sirupsen/logrus v1.6.0 | ||
github.com/sonatype-nexus-community/go-sona-types v0.0.12 | ||
github.com/sonatype-nexus-community/go-sona-types v0.1.1 | ||
github.com/spf13/afero v1.3.4 // indirect | ||
github.com/spf13/cast v1.3.1 // indirect | ||
github.com/spf13/cobra v1.0.0 | ||
|
@@ -37,10 +37,10 @@ require ( | |
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c | ||
) | ||
|
||
// fix vulnerability: CVE-2020-15114 in etcd v3.3.13+incompatible | ||
replace github.com/coreos/etcd => github.com/coreos/etcd v3.3.24+incompatible | ||
// // fix vulnerability: CVE-2020-15114 in etcd v3.3.13+incompatible | ||
// replace github.com/coreos/etcd => github.com/coreos/etcd v3.3.24+incompatible | ||
|
||
// fix vulnerability: CVE-2021-3121 in github.com/gogo/protobuf v1.2.1 | ||
replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 | ||
// // fix vulnerability: CVE-2021-3121 in github.com/gogo/protobuf v1.2.1 | ||
// replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 | ||
Comment on lines
+43
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have these commented out for easy local testing of vulnerable dependencies |
||
|
||
go 1.13 |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,51 +20,37 @@ import ( | |
"os" | ||
|
||
log "github.com/sirupsen/logrus" | ||
"github.com/sonatype-nexus-community/go-sona-types/ossindex/types" | ||
ossIndexTypes "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" | ||
"github.com/sonatype-nexus-community/nancy/buildversion" | ||
"github.com/sonatype-nexus-community/nancy/types" | ||
) | ||
|
||
// LogResults will given a number of expected results and the results themselves, log the | ||
// results. | ||
func LogResults(formatter log.Formatter, packageCount int, coordinates []types.Coordinate, invalidCoordinates []types.Coordinate, exclusions []string) int { | ||
vulnerableCount := 0 | ||
func LogResults(formatter log.Formatter, packageCount int, coordinates map[string]ossIndexTypes.Coordinate, invalidCoordinates []ossIndexTypes.Coordinate, vulnerableCoordinates map[string]types.Dependency, exclusions []string) int { | ||
|
||
for _, c := range coordinates { | ||
c.ExcludeVulnerabilities(exclusions) | ||
if exclusions == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I moved this further up because it seemed odd it would make this AFTER we try using exclusions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so the only reason it was down there was b/c if you log it it would not work correctly i believe. So if you passed in nil we wanted it to present to the user as So really we only do it for presentation. If we can find a better way im cool with it. But moving it up or down doesn't mean much just has to be before the log statement at line 46 hits. |
||
exclusions = make([]string, 0) | ||
} | ||
|
||
var auditedCoordinates []types.Coordinate | ||
var vulnerableCoordinates []types.Coordinate | ||
|
||
for i := 0; i < len(coordinates); i++ { | ||
coordinate := coordinates[i] | ||
if coordinate.IsVulnerable() { | ||
vulnerableCount++ | ||
vulnerableCoordinates = append(vulnerableCoordinates, coordinate) | ||
} | ||
auditedCoordinates = append(auditedCoordinates, coordinate) | ||
for _, c := range vulnerableCoordinates { | ||
c.Coordinate.ExcludeVulnerabilities(exclusions) | ||
} | ||
|
||
if invalidCoordinates == nil { | ||
invalidCoordinates = make([]types.Coordinate, 0) | ||
} | ||
if exclusions == nil { | ||
exclusions = make([]string, 0) | ||
} | ||
if vulnerableCoordinates == nil { | ||
vulnerableCoordinates = make([]types.Coordinate, 0) | ||
invalidCoordinates = make([]ossIndexTypes.Coordinate, 0) | ||
} | ||
|
||
log.SetFormatter(formatter) | ||
log.SetOutput(os.Stdout) | ||
log.WithFields(log.Fields{ | ||
"exclusions": exclusions, | ||
"num_audited": packageCount, | ||
"num_vulnerable": vulnerableCount, | ||
"audited": auditedCoordinates, | ||
"vulnerable": vulnerableCoordinates, | ||
"invalid": invalidCoordinates, | ||
"version": buildversion.BuildVersion, | ||
"exclusions": exclusions, | ||
"num_audited": packageCount, | ||
"audited": coordinates, | ||
"vulnerable": vulnerableCoordinates, | ||
"invalid": invalidCoordinates, | ||
"version": buildversion.BuildVersion, | ||
}).Info("") | ||
|
||
return vulnerableCount | ||
return len(vulnerableCoordinates) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,8 @@ import ( | |
"github.com/logrusorgru/aurora" | ||
"github.com/shopspring/decimal" | ||
. "github.com/sirupsen/logrus" | ||
"github.com/sonatype-nexus-community/go-sona-types/ossindex/types" | ||
ossIndexTypes "github.com/sonatype-nexus-community/go-sona-types/ossindex/types" | ||
"github.com/sonatype-nexus-community/nancy/types" | ||
) | ||
|
||
var ( | ||
|
@@ -47,7 +48,7 @@ type AuditLogTextFormatter struct { | |
NoColor bool | ||
} | ||
|
||
func logPackage(sb *strings.Builder, noColor bool, coordinate types.Coordinate) { | ||
func logPackage(sb *strings.Builder, noColor bool, coordinate ossIndexTypes.Coordinate) { | ||
au := aurora.NewAurora(!noColor) | ||
|
||
sb.WriteString( | ||
|
@@ -57,7 +58,7 @@ func logPackage(sb *strings.Builder, noColor bool, coordinate types.Coordinate) | |
) | ||
} | ||
|
||
func logInvalidSemVerWarning(sb *strings.Builder, noColor bool, quiet bool, invalidPurls []types.Coordinate) { | ||
func logInvalidSemVerWarning(sb *strings.Builder, noColor bool, quiet bool, invalidPurls []ossIndexTypes.Coordinate) { | ||
if !quiet { | ||
if len(invalidPurls) > 0 { | ||
au := aurora.NewAurora(!noColor) | ||
|
@@ -76,19 +77,19 @@ func logInvalidSemVerWarning(sb *strings.Builder, noColor bool, quiet bool, inva | |
} | ||
} | ||
|
||
func logVulnerablePackage(sb *strings.Builder, noColor bool, coordinate types.Coordinate) { | ||
func logVulnerablePackage(sb *strings.Builder, noColor bool, coordinate types.Dependency) { | ||
au := aurora.NewAurora(!noColor) | ||
sb.WriteString(fmt.Sprintf( | ||
"%s\n%s \n", | ||
au.Bold(au.Red(coordinate.Coordinates)).String(), | ||
au.Red(strconv.Itoa(len(coordinate.Vulnerabilities))+" known vulnerabilities affecting installed version").String(), | ||
au.Bold(au.Red(coordinate.Coordinate.Coordinates)).String(), | ||
au.Red(strconv.Itoa(len(coordinate.Coordinate.Vulnerabilities))+" known vulnerabilities affecting installed version").String(), | ||
)) | ||
|
||
sort.Slice(coordinate.Vulnerabilities, func(i, j int) bool { | ||
return coordinate.Vulnerabilities[i].CvssScore.GreaterThan(coordinate.Vulnerabilities[j].CvssScore) | ||
sort.Slice(coordinate.Coordinate.Vulnerabilities, func(i, j int) bool { | ||
return coordinate.Coordinate.Vulnerabilities[i].CvssScore.GreaterThan(coordinate.Coordinate.Vulnerabilities[j].CvssScore) | ||
}) | ||
|
||
for _, v := range coordinate.Vulnerabilities { | ||
for _, v := range coordinate.Coordinate.Vulnerabilities { | ||
if !v.Excluded { | ||
t := table.NewWriter() | ||
t.SetStyle(table.StyleBold) | ||
|
@@ -102,6 +103,7 @@ func logVulnerablePackage(sb *strings.Builder, noColor bool, coordinate types.Co | |
t.AppendRow([]interface{}{"CVSS Vector", v.CvssVector}) | ||
t.AppendSeparator() | ||
t.AppendRow([]interface{}{"Link for more info", v.Reference}) | ||
|
||
sb.WriteString(t.Render() + "\n") | ||
} | ||
} | ||
|
@@ -134,66 +136,73 @@ func scoreAssessment(score decimal.Decimal) string { | |
return "Low" | ||
} | ||
|
||
func groupAndPrint(vulnerable []types.Coordinate, nonVulnerable []types.Coordinate, quiet bool, noColor bool, sb *strings.Builder) { | ||
func groupAndPrint(vulnerableDependencies map[string]types.Dependency, nonVulnerable map[string]ossIndexTypes.Coordinate, quiet bool, noColor bool, sb *strings.Builder) { | ||
if !quiet { | ||
sb.WriteString("\n") | ||
for _, v := range nonVulnerable { | ||
logPackage(sb, noColor, v) | ||
} | ||
sb.WriteString(fmt.Sprintf("\n%d Non Vulnerable Packages\n\n", len(nonVulnerable))) | ||
} | ||
if len(vulnerable) > 0 { | ||
for _, v := range vulnerable { | ||
if len(vulnerableDependencies) > 0 { | ||
for _, v := range vulnerableDependencies { | ||
logVulnerablePackage(sb, noColor, v) | ||
} | ||
sb.WriteString(fmt.Sprintf("\n%d Vulnerable Packages\n\n", len(vulnerable))) | ||
sb.WriteString(fmt.Sprintf("\n%d Vulnerable Packages\n\n", len(vulnerableDependencies))) | ||
} | ||
} | ||
|
||
func (f AuditLogTextFormatter) Format(entry *Entry) ([]byte, error) { | ||
auditedEntries := entry.Data["audited"] | ||
invalidEntries := entry.Data["invalid"] | ||
packageCount := entry.Data["num_audited"] | ||
numVulnerable := entry.Data["num_vulnerable"] | ||
vulnerableEntries := entry.Data["vulnerable"] | ||
buildVersion := entry.Data["version"] | ||
if auditedEntries != nil && invalidEntries != nil && packageCount != nil && numVulnerable != nil && buildVersion != nil { | ||
auditedEntries := entry.Data["audited"].([]types.Coordinate) | ||
invalidEntries := entry.Data["invalid"].([]types.Coordinate) | ||
packageCount := entry.Data["num_audited"].(int) | ||
numVulnerable := entry.Data["num_vulnerable"].(int) | ||
if auditedEntries != nil && invalidEntries != nil && vulnerableEntries != nil && buildVersion != nil { | ||
auditedEntries := entry.Data["audited"].(map[string]ossIndexTypes.Coordinate) | ||
vulnerableEntries := entry.Data["vulnerable"].(map[string]types.Dependency) | ||
invalidEntries := entry.Data["invalid"].([]ossIndexTypes.Coordinate) | ||
|
||
var sb strings.Builder | ||
|
||
w := tabwriter.NewWriter(&sb, 9, 3, 0, '\t', 0) | ||
_ = w.Flush() | ||
|
||
logInvalidSemVerWarning(&sb, f.NoColor, f.Quiet, invalidEntries) | ||
nonVulnerablePackages, vulnerablePackages := splitPackages(auditedEntries) | ||
|
||
groupAndPrint(vulnerablePackages, nonVulnerablePackages, f.Quiet, f.NoColor, &sb) | ||
groupAndPrint(vulnerableEntries, auditedEntries, f.Quiet, f.NoColor, &sb) | ||
|
||
au := aurora.NewAurora(!f.NoColor) | ||
|
||
var updates []string | ||
for _, v := range vulnerableEntries { | ||
if v.UpdateCoordinate.Coordinates != "" && v.Update != nil { | ||
var issueTitles []string | ||
for _, v := range v.Coordinate.Vulnerabilities { | ||
issueTitles = append(issueTitles, v.Cve) | ||
} | ||
comment := au.Green(fmt.Sprintf("// fix issues: %s in %s %s\n", strings.Join(issueTitles, ", "), v.Name, v.Version)).String() | ||
replace := au.Blue(fmt.Sprintf("replace %s => %s %s\n\n", v.Update.Path, v.Update.Path, v.Update.Version)).String() | ||
updates = append(updates, comment, replace) | ||
} | ||
} | ||
|
||
if len(updates) > 0 { | ||
sb.WriteString(au.Bold("I found some updated versions you can try out, that have no known vulnerabilities!\n\nTry the following in your go.mod file:\n\n").String()) | ||
for _, v := range updates { | ||
sb.WriteString(au.Italic(v).String()) | ||
} | ||
} | ||
|
||
t := table.NewWriter() | ||
t.SetStyle(table.StyleBold) | ||
t.SetTitle("Summary") | ||
t.AppendRow([]interface{}{"Audited Dependencies", strconv.Itoa(packageCount)}) | ||
t.AppendRow([]interface{}{"Audited Dependencies", strconv.Itoa(len(auditedEntries))}) | ||
t.AppendSeparator() | ||
t.AppendRow([]interface{}{"Vulnerable Dependencies", au.Bold(au.Red(strconv.Itoa(numVulnerable)))}) | ||
t.AppendRow([]interface{}{"Vulnerable Dependencies", au.Bold(au.Red(strconv.Itoa(len(vulnerableEntries))))}) | ||
sb.WriteString(t.Render()) | ||
sb.WriteString("\n") | ||
|
||
return []byte(sb.String()), nil | ||
} | ||
return nil, errors.New("fields passed did not match the expected values for an audit log. You should probably look at setting the formatter to something else") | ||
} | ||
|
||
func splitPackages(entries []types.Coordinate) (nonVulnerable []types.Coordinate, vulnerable []types.Coordinate) { | ||
for _, v := range entries { | ||
if v.IsVulnerable() { | ||
vulnerable = append(vulnerable, v) | ||
} else { | ||
nonVulnerable = append(nonVulnerable, v) | ||
} | ||
} | ||
return | ||
} | ||
Comment on lines
-190
to
-199
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This wasn't even being used, or rather it was, but we already had two lists of data. I removed it because LOL |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,21 +39,20 @@ func (f CsvFormatter) Format(entry *Entry) ([]byte, error) { | |
// source of the official loggers. | ||
auditedEntries := entry.Data["audited"] | ||
invalidEntries := entry.Data["invalid"] | ||
packageCount := entry.Data["num_audited"] | ||
numVulnerable := entry.Data["num_vulnerable"] | ||
buildVersion := entry.Data["version"] | ||
vulnerableEntries := entry.Data["vulnerable"] | ||
|
||
if auditedEntries != nil && invalidEntries != nil && packageCount != nil && numVulnerable != nil && buildVersion != nil { | ||
if auditedEntries != nil && invalidEntries != nil && vulnerableEntries != nil && buildVersion != nil { | ||
auditedEntries := entry.Data["audited"].([]types.Coordinate) | ||
invalidEntries := entry.Data["invalid"].([]types.Coordinate) | ||
packageCount := entry.Data["num_audited"].(int) | ||
numVulnerable := entry.Data["num_vulnerable"].(int) | ||
buildVersion := entry.Data["version"].(string) | ||
numVulnerable := len(vulnerableEntries.(map[string]interface{})) | ||
numPackages := len(auditedEntries) | ||
|
||
var summaryHeader = []string{"Audited Count", "Vulnerable Count", "Build Version"} | ||
var invalidHeader = []string{"Count", "Package", "Reason"} | ||
var auditedHeader = []string{"Count", "Package", "Is Vulnerable", "Num Vulnerabilities", "Vulnerabilities"} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we also maybe add these "can be updated" packages to the csv output too?? Maybe a column of "Latest non-vulnerable version" or something like that?? |
||
var summaryRow = []string{strconv.Itoa(packageCount), strconv.Itoa(numVulnerable), buildVersion} | ||
var summaryRow = []string{strconv.Itoa(numPackages), strconv.Itoa(numVulnerable), buildVersion} | ||
|
||
var buf bytes.Buffer | ||
w := csv.NewWriter(&buf) | ||
|
@@ -105,7 +104,7 @@ func (f CsvFormatter) Format(entry *Entry) ([]byte, error) { | |
auditEntry := auditedEntries[i-1] | ||
if auditEntry.IsVulnerable() || !f.Quiet { | ||
jsonVulns, _ := json.Marshal(auditEntry.Vulnerabilities) | ||
if err = f.write(w, []string{"[" + strconv.Itoa(i) + "/" + strconv.Itoa(packageCount) + "]", auditEntry.Coordinates, strconv.FormatBool(auditEntry.IsVulnerable()), strconv.Itoa(len(auditEntry.Vulnerabilities)), string(jsonVulns)}); err != nil { | ||
if err = f.write(w, []string{"[" + strconv.Itoa(i) + "/" + strconv.Itoa(numPackages) + "]", auditEntry.Coordinates, strconv.FormatBool(auditEntry.IsVulnerable()), strconv.Itoa(len(auditEntry.Vulnerabilities)), string(jsonVulns)}); err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have these commented out for easy local testing of vulnerable dependencies