mirror of
https://github.com/securego/gosec.git
synced 2024-12-25 12:05:52 +00:00
Add golint format to output format (#428)
Signed-off-by: Hiroki Suezawa <suezawa@gmail.com>
This commit is contained in:
parent
57c3788fe5
commit
79fbf3af8d
6 changed files with 54 additions and 2 deletions
|
@ -210,7 +210,7 @@ gosec -tag debug,ignore ./...
|
||||||
|
|
||||||
### Output formats
|
### Output formats
|
||||||
|
|
||||||
gosec currently supports text, json, yaml, csv, sonarqube and JUnit XML output formats. By default
|
gosec currently supports text, json, yaml, csv, sonarqube, JUnit XML and golint output formats. By default
|
||||||
results will be reported to stdout, but can also be written to an output
|
results will be reported to stdout, but can also be written to an output
|
||||||
file. The output format is controlled by the '-fmt' flag, and the output file is controlled by the '-out' flag as follows:
|
file. The output format is controlled by the '-fmt' flag, and the output file is controlled by the '-out' flag as follows:
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ var (
|
||||||
flagIgnoreNoSec = flag.Bool("nosec", false, "Ignores #nosec comments when set")
|
flagIgnoreNoSec = flag.Bool("nosec", false, "Ignores #nosec comments when set")
|
||||||
|
|
||||||
// format output
|
// format output
|
||||||
flagFormat = flag.String("fmt", "text", "Set output format. Valid options are: json, yaml, csv, junit-xml, html, sonarqube, or text")
|
flagFormat = flag.String("fmt", "text", "Set output format. Valid options are: json, yaml, csv, junit-xml, html, sonarqube, golint or text")
|
||||||
|
|
||||||
// #nosec alternative tag
|
// #nosec alternative tag
|
||||||
flagAlternativeNoSec = flag.String("nosec-tag", "", "Set an alternative string for #nosec. Some examples: #dontanalyze, #falsepositive")
|
flagAlternativeNoSec = flag.String("nosec-tag", "", "Set an alternative string for #nosec. Some examples: #dontanalyze, #falsepositive")
|
||||||
|
|
4
issue.go
4
issue.go
|
@ -83,6 +83,7 @@ type Issue struct {
|
||||||
File string `json:"file"` // File name we found it in
|
File string `json:"file"` // File name we found it in
|
||||||
Code string `json:"code"` // Impacted code line
|
Code string `json:"code"` // Impacted code line
|
||||||
Line string `json:"line"` // Line number in file
|
Line string `json:"line"` // Line number in file
|
||||||
|
Col string `json:"column"` // Column number in line
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetaData is embedded in all gosec rules. The Severity, Confidence and What message
|
// MetaData is embedded in all gosec rules. The Severity, Confidence and What message
|
||||||
|
@ -142,6 +143,8 @@ func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score,
|
||||||
line = fmt.Sprintf("%d-%d", start, end)
|
line = fmt.Sprintf("%d-%d", start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
col := strconv.Itoa(fobj.Position(node.Pos()).Column)
|
||||||
|
|
||||||
// #nosec
|
// #nosec
|
||||||
if file, err := os.Open(fobj.Name()); err == nil {
|
if file, err := os.Open(fobj.Name()); err == nil {
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
@ -156,6 +159,7 @@ func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score,
|
||||||
return &Issue{
|
return &Issue{
|
||||||
File: name,
|
File: name,
|
||||||
Line: line,
|
Line: line,
|
||||||
|
Col: col,
|
||||||
RuleID: ruleID,
|
RuleID: ruleID,
|
||||||
What: desc,
|
What: desc,
|
||||||
Confidence: confidence,
|
Confidence: confidence,
|
||||||
|
|
|
@ -41,6 +41,7 @@ var _ = Describe("Issue", func() {
|
||||||
Expect(issue).ShouldNot(BeNil())
|
Expect(issue).ShouldNot(BeNil())
|
||||||
Expect(issue.Code).Should(MatchRegexp(`"bar"`))
|
Expect(issue.Code).Should(MatchRegexp(`"bar"`))
|
||||||
Expect(issue.Line).Should(Equal("2"))
|
Expect(issue.Line).Should(Equal("2"))
|
||||||
|
Expect(issue.Col).Should(Equal("16"))
|
||||||
Expect(issue.Cwe.ID).Should(Equal(""))
|
Expect(issue.Cwe.ID).Should(Equal(""))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@ var _ = Describe("Issue", func() {
|
||||||
Expect(issue).ShouldNot(BeNil())
|
Expect(issue).ShouldNot(BeNil())
|
||||||
Expect(issue.File).Should(MatchRegexp("foo.go"))
|
Expect(issue.File).Should(MatchRegexp("foo.go"))
|
||||||
Expect(issue.Line).Should(MatchRegexp("3-4"))
|
Expect(issue.Line).Should(MatchRegexp("3-4"))
|
||||||
|
Expect(issue.Col).Should(Equal("21"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should maintain the provided severity score", func() {
|
It("should maintain the provided severity score", func() {
|
||||||
|
|
|
@ -99,6 +99,8 @@ func CreateReport(w io.Writer, format string, rootPaths []string, issues []*gose
|
||||||
err = reportFromPlaintextTemplate(w, text, data)
|
err = reportFromPlaintextTemplate(w, text, data)
|
||||||
case "sonarqube":
|
case "sonarqube":
|
||||||
err = reportSonarqube(rootPaths, w, data)
|
err = reportSonarqube(rootPaths, w, data)
|
||||||
|
case "golint":
|
||||||
|
err = reportGolint(w, data)
|
||||||
default:
|
default:
|
||||||
err = reportFromPlaintextTemplate(w, text, data)
|
err = reportFromPlaintextTemplate(w, text, data)
|
||||||
}
|
}
|
||||||
|
@ -202,6 +204,36 @@ func reportCSV(w io.Writer, data *reportInfo) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reportGolint(w io.Writer, data *reportInfo) error {
|
||||||
|
// Output Sample:
|
||||||
|
// /tmp/main.go:11:14: [CWE-310] RSA keys should be at least 2048 bits (Rule:G403, Severity:MEDIUM, Confidence:HIGH)
|
||||||
|
|
||||||
|
for _, issue := range data.Issues {
|
||||||
|
what := issue.What
|
||||||
|
if issue.Cwe.ID != "" {
|
||||||
|
what = fmt.Sprintf("[CWE-%s] %s", issue.Cwe.ID, issue.What)
|
||||||
|
}
|
||||||
|
|
||||||
|
// issue.Line uses "start-end" format for multiple line detection.
|
||||||
|
lines := strings.Split(issue.Line, "-")
|
||||||
|
start := lines[0]
|
||||||
|
|
||||||
|
_, err := fmt.Fprintf(w, "%s:%s:%s: %s (Rule:%s, Severity:%s, Confidence:%s)\n",
|
||||||
|
issue.File,
|
||||||
|
start,
|
||||||
|
issue.Col,
|
||||||
|
what,
|
||||||
|
issue.RuleID,
|
||||||
|
issue.Severity.String(),
|
||||||
|
issue.Confidence.String(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func reportJUnitXML(w io.Writer, data *reportInfo) error {
|
func reportJUnitXML(w io.Writer, data *reportInfo) error {
|
||||||
groupedData := groupDataByRules(data)
|
groupedData := groupDataByRules(data)
|
||||||
junitXMLStruct := createJUnitXMLStruct(groupedData)
|
junitXMLStruct := createJUnitXMLStruct(groupedData)
|
||||||
|
|
|
@ -15,6 +15,7 @@ func createIssue(ruleID string, cwe gosec.Cwe) gosec.Issue {
|
||||||
return gosec.Issue{
|
return gosec.Issue{
|
||||||
File: "/home/src/project/test.go",
|
File: "/home/src/project/test.go",
|
||||||
Line: "1",
|
Line: "1",
|
||||||
|
Col: "1",
|
||||||
RuleID: ruleID,
|
RuleID: ruleID,
|
||||||
What: "test",
|
What: "test",
|
||||||
Confidence: gosec.High,
|
Confidence: gosec.High,
|
||||||
|
@ -391,5 +392,18 @@ var _ = Describe("Formatter", func() {
|
||||||
Expect(result).To(ContainSubstring(expectation))
|
Expect(result).To(ContainSubstring(expectation))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
It("golint formatted report should contain the CWE mapping", func() {
|
||||||
|
for _, rule := range grules {
|
||||||
|
cwe := gosec.IssueToCWE[rule]
|
||||||
|
issue := createIssue(rule, cwe)
|
||||||
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
CreateReport(buf, "golint", []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
|
||||||
|
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(string(buf.Bytes())).To(Equal(expect))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue