mirror of
https://github.com/securego/gosec.git
synced 2024-11-05 19:45:51 +00:00
Handle gosec version in SARIF report
This commit is contained in:
parent
51f7411573
commit
d040f0725f
22 changed files with 151 additions and 96 deletions
|
@ -216,23 +216,23 @@ func getPrintedFormat(format string, verbose string) string {
|
||||||
return fileFormat
|
return fileFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
func printReport(format string, color bool, rootPaths []string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
|
func printReport(format string, color bool, rootPaths []string, reportInfo *gosec.ReportInfo) error {
|
||||||
|
|
||||||
err := report.CreateReport(os.Stdout, format, color, rootPaths, issues, metrics, errors)
|
err := report.CreateReport(os.Stdout, format, color, rootPaths, reportInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveReport(filename, format string, rootPaths []string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
|
func saveReport(filename, format string, rootPaths []string, reportInfo *gosec.ReportInfo) error {
|
||||||
|
|
||||||
outfile, err := os.Create(filename)
|
outfile, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer outfile.Close() // #nosec G307
|
defer outfile.Close() // #nosec G307
|
||||||
err = report.CreateReport(outfile, format, false, rootPaths, issues, metrics, errors)
|
err = report.CreateReport(outfile, format, false, rootPaths, reportInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -383,14 +383,16 @@ func main() {
|
||||||
// Create output report
|
// Create output report
|
||||||
rootPaths := getRootPaths(flag.Args())
|
rootPaths := getRootPaths(flag.Args())
|
||||||
|
|
||||||
|
reportInfo := gosec.NewReportInfo(issues, metrics, errors).WithVersion(Version)
|
||||||
|
|
||||||
if *flagOutput == "" || *flagStdOut {
|
if *flagOutput == "" || *flagStdOut {
|
||||||
var fileFormat = getPrintedFormat(*flagOutput, *flagVerbose)
|
var fileFormat = getPrintedFormat(*flagOutput, *flagVerbose)
|
||||||
if err := printReport(fileFormat, *flagColor, rootPaths, issues, metrics, errors); err != nil {
|
if err := printReport(fileFormat, *flagColor, rootPaths, reportInfo); err != nil {
|
||||||
logger.Fatal((err))
|
logger.Fatal((err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if *flagOutput != "" {
|
if *flagOutput != "" {
|
||||||
if err := saveReport(*flagOutput, *flagFormat, rootPaths, issues, metrics, errors); err != nil {
|
if err := saveReport(*flagOutput, *flagFormat, rootPaths, reportInfo); err != nil {
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -3,13 +3,14 @@ module github.com/securego/gosec/v2
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.1.1
|
github.com/google/uuid v1.1.1
|
||||||
github.com/gookit/color v1.4.2
|
github.com/gookit/color v1.4.2
|
||||||
|
github.com/lib/pq v1.9.0
|
||||||
github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880
|
github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880
|
||||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354
|
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354
|
||||||
github.com/onsi/ginkgo v1.16.1
|
github.com/onsi/ginkgo v1.16.1
|
||||||
github.com/onsi/gomega v1.11.0
|
github.com/onsi/gomega v1.11.0
|
||||||
golang.org/x/mod v0.4.1 // indirect
|
golang.org/x/mod v0.4.1 // indirect
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
|
||||||
golang.org/x/text v0.3.5 // indirect
|
golang.org/x/text v0.3.5
|
||||||
golang.org/x/tools v0.1.0
|
golang.org/x/tools v0.1.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
24
report.go
Normal file
24
report.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package gosec
|
||||||
|
|
||||||
|
// ReportInfo this is report information
|
||||||
|
type ReportInfo struct {
|
||||||
|
Errors map[string][]Error `json:"Golang errors"`
|
||||||
|
Issues []*Issue
|
||||||
|
Stats *Metrics
|
||||||
|
GosecVersion string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReportInfo instantiate a ReportInfo
|
||||||
|
func NewReportInfo(issues []*Issue, metrics *Metrics, errors map[string][]Error) *ReportInfo {
|
||||||
|
return &ReportInfo{
|
||||||
|
Errors: errors,
|
||||||
|
Issues: issues,
|
||||||
|
Stats: metrics,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithVersion defines the version of gosec used to generate the report
|
||||||
|
func (r *ReportInfo) WithVersion(version string) *ReportInfo {
|
||||||
|
r.GosecVersion = version
|
||||||
|
return r
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
package core
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/securego/gosec/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
//ReportInfo this is report information
|
|
||||||
type ReportInfo struct {
|
|
||||||
Errors map[string][]gosec.Error `json:"Golang errors"`
|
|
||||||
Issues []*gosec.Issue
|
|
||||||
Stats *gosec.Metrics
|
|
||||||
}
|
|
|
@ -2,12 +2,13 @@ package csv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in csv format to the output writer
|
//WriteReport write a report in csv format to the output writer
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
out := csv.NewWriter(w)
|
out := csv.NewWriter(w)
|
||||||
defer out.Flush()
|
defer out.Flush()
|
||||||
for _, issue := range data.Issues {
|
for _, issue := range data.Issues {
|
||||||
|
|
|
@ -15,8 +15,9 @@
|
||||||
package report
|
package report
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"github.com/securego/gosec/v2/report/csv"
|
"github.com/securego/gosec/v2/report/csv"
|
||||||
"github.com/securego/gosec/v2/report/golint"
|
"github.com/securego/gosec/v2/report/golint"
|
||||||
"github.com/securego/gosec/v2/report/html"
|
"github.com/securego/gosec/v2/report/html"
|
||||||
|
@ -26,7 +27,6 @@ import (
|
||||||
"github.com/securego/gosec/v2/report/sonar"
|
"github.com/securego/gosec/v2/report/sonar"
|
||||||
"github.com/securego/gosec/v2/report/text"
|
"github.com/securego/gosec/v2/report/text"
|
||||||
"github.com/securego/gosec/v2/report/yaml"
|
"github.com/securego/gosec/v2/report/yaml"
|
||||||
"io"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Format enumerates the output format for reported issues
|
// Format enumerates the output format for reported issues
|
||||||
|
@ -51,12 +51,7 @@ const (
|
||||||
|
|
||||||
// CreateReport generates a report based for the supplied issues and metrics given
|
// CreateReport generates a report based for the supplied issues and metrics given
|
||||||
// the specified format. The formats currently accepted are: json, yaml, csv, junit-xml, html, sonarqube, golint and text.
|
// the specified format. The formats currently accepted are: json, yaml, csv, junit-xml, html, sonarqube, golint and text.
|
||||||
func CreateReport(w io.Writer, format string, enableColor bool, rootPaths []string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
|
func CreateReport(w io.Writer, format string, enableColor bool, rootPaths []string, data *gosec.ReportInfo) error {
|
||||||
data := &core.ReportInfo{
|
|
||||||
Errors: errors,
|
|
||||||
Issues: issues,
|
|
||||||
Stats: metrics,
|
|
||||||
}
|
|
||||||
var err error
|
var err error
|
||||||
switch format {
|
switch format {
|
||||||
case "json":
|
case "json":
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
"github.com/securego/gosec/v2/cwe"
|
"github.com/securego/gosec/v2/cwe"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"github.com/securego/gosec/v2/report/junit"
|
"github.com/securego/gosec/v2/report/junit"
|
||||||
"github.com/securego/gosec/v2/report/sonar"
|
"github.com/securego/gosec/v2/report/sonar"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
@ -37,10 +36,10 @@ func createIssue(ruleID string, weakness *cwe.Weakness) gosec.Issue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createReportInfo(rule string, weakness *cwe.Weakness) core.ReportInfo {
|
func createReportInfo(rule string, weakness *cwe.Weakness) gosec.ReportInfo {
|
||||||
issue := createIssue(rule, weakness)
|
issue := createIssue(rule, weakness)
|
||||||
metrics := gosec.Metrics{}
|
metrics := gosec.Metrics{}
|
||||||
return core.ReportInfo{
|
return gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
&issue,
|
&issue,
|
||||||
|
@ -61,7 +60,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
Context("when converting to Sonarqube issues", func() {
|
Context("when converting to Sonarqube issues", func() {
|
||||||
It("it should parse the report info", func() {
|
It("it should parse the report info", func() {
|
||||||
data := &core.ReportInfo{
|
data := &gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
{
|
{
|
||||||
|
@ -109,7 +108,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("it should parse the report info with files in subfolders", func() {
|
It("it should parse the report info with files in subfolders", func() {
|
||||||
data := &core.ReportInfo{
|
data := &gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
{
|
{
|
||||||
|
@ -156,7 +155,7 @@ var _ = Describe("Formatter", func() {
|
||||||
Expect(*issues).To(Equal(*want))
|
Expect(*issues).To(Equal(*want))
|
||||||
})
|
})
|
||||||
It("it should not parse the report info for files from other projects", func() {
|
It("it should not parse the report info for files from other projects", func() {
|
||||||
data := &core.ReportInfo{
|
data := &gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
{
|
{
|
||||||
|
@ -188,7 +187,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("it should parse the report info for multiple projects projects", func() {
|
It("it should parse the report info for multiple projects projects", func() {
|
||||||
data := &core.ReportInfo{
|
data := &gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
{
|
{
|
||||||
|
@ -264,7 +263,7 @@ var _ = Describe("Formatter", func() {
|
||||||
It("preserves order of issues", func() {
|
It("preserves order of issues", func() {
|
||||||
issues := []*gosec.Issue{createIssueWithFileWhat("i1", "1"), createIssueWithFileWhat("i2", "2"), createIssueWithFileWhat("i3", "1")}
|
issues := []*gosec.Issue{createIssueWithFileWhat("i1", "1"), createIssueWithFileWhat("i2", "2"), createIssueWithFileWhat("i3", "1")}
|
||||||
|
|
||||||
junitReport := junit.GenerateReport(&core.ReportInfo{Issues: issues})
|
junitReport := junit.GenerateReport(&gosec.ReportInfo{Issues: issues})
|
||||||
|
|
||||||
testSuite := junitReport.Testsuites[0]
|
testSuite := junitReport.Testsuites[0]
|
||||||
|
|
||||||
|
@ -290,7 +289,8 @@ var _ = Describe("Formatter", func() {
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := CreateReport(buf, "csv", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
err := CreateReport(buf, "csv", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
pattern := "/home/src/project/test.go,1,test,HIGH,HIGH,1: testcode,CWE-%s\n"
|
pattern := "/home/src/project/test.go,1,test,HIGH,HIGH,1: testcode,CWE-%s\n"
|
||||||
expect := fmt.Sprintf(pattern, cwe.ID)
|
expect := fmt.Sprintf(pattern, cwe.ID)
|
||||||
|
@ -304,7 +304,8 @@ var _ = Describe("Formatter", func() {
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := CreateReport(buf, "xml", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{NumFiles: 0, NumLines: 0, NumNosec: 0, NumFound: 0}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{NumFiles: 0, NumLines: 0, NumNosec: 0, NumFound: 0}, error)
|
||||||
|
err := CreateReport(buf, "xml", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
pattern := "Results:\n\n\n[/home/src/project/test.go:1] - %s (CWE-%s): test (Confidence: HIGH, Severity: HIGH)\n > 1: testcode\n\n\n\nSummary:\n Files: 0\n Lines: 0\n Nosec: 0\n Issues: 0\n\n"
|
pattern := "Results:\n\n\n[/home/src/project/test.go:1] - %s (CWE-%s): test (Confidence: HIGH, Severity: HIGH)\n > 1: testcode\n\n\n\nSummary:\n Files: 0\n Lines: 0\n Nosec: 0\n Issues: 0\n\n"
|
||||||
expect := fmt.Sprintf(pattern, rule, cwe.ID)
|
expect := fmt.Sprintf(pattern, rule, cwe.ID)
|
||||||
|
@ -324,7 +325,8 @@ var _ = Describe("Formatter", func() {
|
||||||
err := enc.Encode(data)
|
err := enc.Encode(data)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err = CreateReport(buf, "json", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
err = CreateReport(buf, "json", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
result := stripString(buf.String())
|
result := stripString(buf.String())
|
||||||
expectation := stripString(expect.String())
|
expectation := stripString(expect.String())
|
||||||
|
@ -344,7 +346,8 @@ var _ = Describe("Formatter", func() {
|
||||||
err := enc.Encode(data)
|
err := enc.Encode(data)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err = CreateReport(buf, "html", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
err = CreateReport(buf, "html", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
result := stripString(buf.String())
|
result := stripString(buf.String())
|
||||||
expectation := stripString(expect.String())
|
expectation := stripString(expect.String())
|
||||||
|
@ -364,7 +367,8 @@ var _ = Describe("Formatter", func() {
|
||||||
err := enc.Encode(data)
|
err := enc.Encode(data)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err = CreateReport(buf, "yaml", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
err = CreateReport(buf, "yaml", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
result := stripString(buf.String())
|
result := stripString(buf.String())
|
||||||
expectation := stripString(expect.String())
|
expectation := stripString(expect.String())
|
||||||
|
@ -384,7 +388,8 @@ var _ = Describe("Formatter", func() {
|
||||||
err := enc.Encode(data)
|
err := enc.Encode(data)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err = CreateReport(buf, "junit-xml", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
err = CreateReport(buf, "junit-xml", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
expectation := stripString(fmt.Sprintf("[/home/src/project/test.go:1] - test (Confidence: 2, Severity: 2, CWE: %s)", cwe.ID))
|
expectation := stripString(fmt.Sprintf("[/home/src/project/test.go:1] - test (Confidence: 2, Severity: 2, CWE: %s)", cwe.ID))
|
||||||
result := stripString(buf.String())
|
result := stripString(buf.String())
|
||||||
|
@ -404,7 +409,8 @@ var _ = Describe("Formatter", func() {
|
||||||
err := enc.Encode(data)
|
err := enc.Encode(data)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err = CreateReport(buf, "text", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
err = CreateReport(buf, "text", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
expectation := stripString(fmt.Sprintf("[/home/src/project/test.go:1] - %s (CWE-%s): test (Confidence: HIGH, Severity: HIGH)", rule, cwe.ID))
|
expectation := stripString(fmt.Sprintf("[/home/src/project/test.go:1] - %s (CWE-%s): test (Confidence: HIGH, Severity: HIGH)", rule, cwe.ID))
|
||||||
result := stripString(buf.String())
|
result := stripString(buf.String())
|
||||||
|
@ -417,7 +423,8 @@ var _ = Describe("Formatter", func() {
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := CreateReport(buf, "sonarqube", false, []string{"/home/src/project"}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
err := CreateReport(buf, "sonarqube", false, []string{"/home/src/project"}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
result := stripString(buf.String())
|
result := stripString(buf.String())
|
||||||
|
@ -438,7 +445,8 @@ var _ = Describe("Formatter", func() {
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := CreateReport(buf, "golint", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
err := CreateReport(buf, "golint", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
pattern := "/home/src/project/test.go:1:1: [CWE-%s] test (Rule:%s, Severity:HIGH, Confidence:HIGH)\n"
|
pattern := "/home/src/project/test.go:1:1: [CWE-%s] test (Rule:%s, Severity:HIGH, Confidence:HIGH)\n"
|
||||||
expect := fmt.Sprintf(pattern, cwe.ID, rule)
|
expect := fmt.Sprintf(pattern, cwe.ID, rule)
|
||||||
|
@ -452,7 +460,8 @@ var _ = Describe("Formatter", func() {
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := CreateReport(buf, "sarif", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, error).WithVersion("v2.7.0")
|
||||||
|
err := CreateReport(buf, "sarif", false, []string{}, reportInfo)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
result := stripString(buf.String())
|
result := stripString(buf.String())
|
||||||
|
|
|
@ -2,13 +2,14 @@ package golint
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in golint format to the output writer
|
//WriteReport write a report in golint format to the output writer
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
// Output Sample:
|
// Output Sample:
|
||||||
// /tmp/main.go:11:14: [CWE-310] RSA keys should be at least 2048 bits (Rule:G403, Severity:MEDIUM, Confidence:HIGH)
|
// /tmp/main.go:11:14: [CWE-310] RSA keys should be at least 2048 bits (Rule:G403, Severity:MEDIUM, Confidence:HIGH)
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package html
|
package html
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in html format to the output writer
|
//WriteReport write a report in html format to the output writer
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
t, e := template.New("gosec").Parse(templateContent)
|
t, e := template.New("gosec").Parse(templateContent)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
|
|
|
@ -2,12 +2,13 @@ package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in json format to the output writer
|
//WriteReport write a report in json format to the output writer
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
raw, err := json.MarshalIndent(data, "", "\t")
|
raw, err := json.MarshalIndent(data, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func generatePlaintext(issue *gosec.Issue) string {
|
func generatePlaintext(issue *gosec.Issue) string {
|
||||||
|
@ -17,7 +16,7 @@ func generatePlaintext(issue *gosec.Issue) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
//GenerateReport Convert a gosec report to a JUnit Report
|
//GenerateReport Convert a gosec report to a JUnit Report
|
||||||
func GenerateReport(data *core.ReportInfo) Report {
|
func GenerateReport(data *gosec.ReportInfo) Report {
|
||||||
var xmlReport Report
|
var xmlReport Report
|
||||||
testsuites := map[string]int{}
|
testsuites := map[string]int{}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,13 @@ package junit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in JUnit format to the output writer
|
//WriteReport write a report in JUnit format to the output writer
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
junitXMLStruct := GenerateReport(data)
|
junitXMLStruct := GenerateReport(data)
|
||||||
raw, err := xml.MarshalIndent(junitXMLStruct, "", "\t")
|
raw, err := xml.MarshalIndent(junitXMLStruct, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -126,6 +126,18 @@ func NewToolComponent(name string, version string, informationURI string) *ToolC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//WithLanguage set Language for the current ToolComponent
|
||||||
|
func (t *ToolComponent) WithLanguage(language string) *ToolComponent {
|
||||||
|
t.Language = language
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
//WithSemanticVersion set SemanticVersion for the current ToolComponent
|
||||||
|
func (t *ToolComponent) WithSemanticVersion(semanticVersion string) *ToolComponent {
|
||||||
|
t.SemanticVersion = semanticVersion
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
//WithReleaseDateUtc set releaseDateUtc for the current ToolComponent
|
//WithReleaseDateUtc set releaseDateUtc for the current ToolComponent
|
||||||
func (t *ToolComponent) WithReleaseDateUtc(releaseDateUtc string) *ToolComponent {
|
func (t *ToolComponent) WithReleaseDateUtc(releaseDateUtc string) *ToolComponent {
|
||||||
t.ReleaseDateUtc = releaseDateUtc
|
t.ReleaseDateUtc = releaseDateUtc
|
||||||
|
|
|
@ -2,18 +2,18 @@ package sarif
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/google/uuid"
|
"sort"
|
||||||
"runtime/debug"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
"github.com/securego/gosec/v2/cwe"
|
"github.com/securego/gosec/v2/cwe"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//GenerateReport Convert a gosec report to a Sarif Report
|
//GenerateReport Convert a gosec report to a Sarif Report
|
||||||
func GenerateReport(rootPaths []string, data *core.ReportInfo) (*Report, error) {
|
func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error) {
|
||||||
|
|
||||||
type rule struct {
|
type rule struct {
|
||||||
index int
|
index int
|
||||||
|
@ -56,7 +56,10 @@ func GenerateReport(rootPaths []string, data *core.ReportInfo) (*Report, error)
|
||||||
results = append(results, result)
|
results = append(results, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
tool := NewTool(buildSarifDriver(rules))
|
sort.SliceStable(rules, func(i, j int) bool { return rules[i].ID < rules[j].ID })
|
||||||
|
sort.SliceStable(cweTaxa, func(i, j int) bool { return cweTaxa[i].ID < cweTaxa[j].ID })
|
||||||
|
|
||||||
|
tool := NewTool(buildSarifDriver(rules, data.GosecVersion))
|
||||||
|
|
||||||
cweTaxonomy := buildCWETaxonomy(cweTaxa)
|
cweTaxonomy := buildCWETaxonomy(cweTaxa)
|
||||||
|
|
||||||
|
@ -108,6 +111,7 @@ func buildCWETaxonomy(taxa []*ReportingDescriptor) *ToolComponent {
|
||||||
WithOrganization(cwe.Organization).
|
WithOrganization(cwe.Organization).
|
||||||
WithShortDescription(NewMultiformatMessageString(cwe.Description)).
|
WithShortDescription(NewMultiformatMessageString(cwe.Description)).
|
||||||
WithIsComprehensive(true).
|
WithIsComprehensive(true).
|
||||||
|
WithLanguage("en").
|
||||||
WithMinimumRequiredLocalizedDataSemanticVersion(cwe.Version).
|
WithMinimumRequiredLocalizedDataSemanticVersion(cwe.Version).
|
||||||
WithTaxa(taxa...)
|
WithTaxa(taxa...)
|
||||||
}
|
}
|
||||||
|
@ -115,22 +119,27 @@ func buildCWETaxonomy(taxa []*ReportingDescriptor) *ToolComponent {
|
||||||
func parseSarifTaxon(weakness *cwe.Weakness) *ReportingDescriptor {
|
func parseSarifTaxon(weakness *cwe.Weakness) *ReportingDescriptor {
|
||||||
return &ReportingDescriptor{
|
return &ReportingDescriptor{
|
||||||
ID: weakness.ID,
|
ID: weakness.ID,
|
||||||
Name: weakness.Name,
|
|
||||||
GUID: uuid3(weakness.SprintID()),
|
GUID: uuid3(weakness.SprintID()),
|
||||||
HelpURI: weakness.SprintURL(),
|
HelpURI: weakness.SprintURL(),
|
||||||
ShortDescription: NewMultiformatMessageString(weakness.Description),
|
FullDescription: NewMultiformatMessageString(weakness.Description),
|
||||||
|
ShortDescription: NewMultiformatMessageString(weakness.Name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildSarifDriver(rules []*ReportingDescriptor) *ToolComponent {
|
func parseSemanticVersion(version string) string {
|
||||||
buildInfo, ok := debug.ReadBuildInfo()
|
if len(version) == 0 {
|
||||||
var gosecVersion string
|
return "devel"
|
||||||
if ok {
|
|
||||||
gosecVersion = buildInfo.Main.Version[1:]
|
|
||||||
} else {
|
|
||||||
gosecVersion = "devel"
|
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(version, "v") {
|
||||||
|
return version[1:]
|
||||||
|
}
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSarifDriver(rules []*ReportingDescriptor, gosecVersion string) *ToolComponent {
|
||||||
|
semanticVersion := parseSemanticVersion(gosecVersion)
|
||||||
return NewToolComponent("gosec", gosecVersion, "https://github.com/securego/gosec/").
|
return NewToolComponent("gosec", gosecVersion, "https://github.com/securego/gosec/").
|
||||||
|
WithSemanticVersion(semanticVersion).
|
||||||
WithSupportedTaxonomies(NewToolComponentReference(cwe.Acronym)).
|
WithSupportedTaxonomies(NewToolComponentReference(cwe.Acronym)).
|
||||||
WithRules(rules...)
|
WithRules(rules...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,13 @@ package sarif
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in SARIF format to the output writer
|
//WriteReport write a report in SARIF format to the output writer
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo, rootPaths []string) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo, rootPaths []string) error {
|
||||||
sr, err := GenerateReport(rootPaths, data)
|
sr, err := GenerateReport(rootPaths, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package sonar
|
package sonar
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/securego/gosec/v2"
|
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -13,7 +13,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
//GenerateReport Convert a gosec report to a Sonar Report
|
//GenerateReport Convert a gosec report to a Sonar Report
|
||||||
func GenerateReport(rootPaths []string, data *core.ReportInfo) (*Report, error) {
|
func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error) {
|
||||||
si := &Report{Issues: []*Issue{}}
|
si := &Report{Issues: []*Issue{}}
|
||||||
for _, issue := range data.Issues {
|
for _, issue := range data.Issues {
|
||||||
sonarFilePath := parseFilePath(issue, rootPaths)
|
sonarFilePath := parseFilePath(issue, rootPaths)
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"github.com/securego/gosec/v2/report/sonar"
|
"github.com/securego/gosec/v2/report/sonar"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,7 +12,7 @@ var _ = Describe("Sonar Formatter", func() {
|
||||||
})
|
})
|
||||||
Context("when converting to Sonarqube issues", func() {
|
Context("when converting to Sonarqube issues", func() {
|
||||||
It("it should parse the report info", func() {
|
It("it should parse the report info", func() {
|
||||||
data := &core.ReportInfo{
|
data := &gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
{
|
{
|
||||||
|
@ -61,7 +60,7 @@ var _ = Describe("Sonar Formatter", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("it should parse the report info with files in subfolders", func() {
|
It("it should parse the report info with files in subfolders", func() {
|
||||||
data := &core.ReportInfo{
|
data := &gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
{
|
{
|
||||||
|
@ -108,7 +107,7 @@ var _ = Describe("Sonar Formatter", func() {
|
||||||
Expect(*issues).To(Equal(*want))
|
Expect(*issues).To(Equal(*want))
|
||||||
})
|
})
|
||||||
It("it should not parse the report info for files from other projects", func() {
|
It("it should not parse the report info for files from other projects", func() {
|
||||||
data := &core.ReportInfo{
|
data := &gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
{
|
{
|
||||||
|
@ -140,7 +139,7 @@ var _ = Describe("Sonar Formatter", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("it should parse the report info for multiple projects projects", func() {
|
It("it should parse the report info for multiple projects projects", func() {
|
||||||
data := &core.ReportInfo{
|
data := &gosec.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
Issues: []*gosec.Issue{
|
Issues: []*gosec.Issue{
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,12 +2,13 @@ package sonar
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in sonar format to the output writer
|
//WriteReport write a report in sonar format to the output writer
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo, rootPaths []string) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo, rootPaths []string) error {
|
||||||
si, err := GenerateReport(rootPaths, data)
|
si, err := GenerateReport(rootPaths, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -4,13 +4,13 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gookit/color"
|
|
||||||
"github.com/securego/gosec/v2"
|
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/gookit/color"
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -20,7 +20,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a (colorized) report in text format
|
//WriteReport write a (colorized) report in text format
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo, enableColor bool) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo, enableColor bool) error {
|
||||||
t, e := template.
|
t, e := template.
|
||||||
New("gosec").
|
New("gosec").
|
||||||
Funcs(plainTextFuncMap(enableColor)).
|
Funcs(plainTextFuncMap(enableColor)).
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package yaml
|
package yaml
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/securego/gosec/v2/report/core"
|
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//WriteReport write a report in yaml format to the output writer
|
//WriteReport write a report in yaml format to the output writer
|
||||||
func WriteReport(w io.Writer, data *core.ReportInfo) error {
|
func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||||
raw, err := yaml.Marshal(data)
|
raw, err := yaml.Marshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
9
tools/tools.go
Normal file
9
tools/tools.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// +build tools
|
||||||
|
|
||||||
|
package tools
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
import (
|
||||||
|
_ "github.com/lib/pq"
|
||||||
|
_ "golang.org/x/text"
|
||||||
|
)
|
Loading…
Reference in a new issue