mirror of
https://github.com/securego/gosec.git
synced 2024-12-25 03:55:54 +00:00
Refactor : Replace Cwe with cwe.Weakness
This commit is contained in:
parent
ddfa25381f
commit
c4f5932ab7
11 changed files with 128 additions and 96 deletions
12
README.md
12
README.md
|
@ -47,6 +47,7 @@ echo "<check sum from the check sum file> gosec_vX.Y.Z_OS.tar.gz" | sha256sum -
|
||||||
|
|
||||||
gosec --help
|
gosec --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### GitHub Action
|
### GitHub Action
|
||||||
|
|
||||||
You can run `gosec` as a GitHub action as follows:
|
You can run `gosec` as a GitHub action as follows:
|
||||||
|
@ -123,7 +124,6 @@ paths, and produce reports in different formats. By default all rules will be
|
||||||
run against the supplied input files. To recursively scan from the current
|
run against the supplied input files. To recursively scan from the current
|
||||||
directory you can supply `./...` as the input argument.
|
directory you can supply `./...` as the input argument.
|
||||||
|
|
||||||
|
|
||||||
### Available rules
|
### Available rules
|
||||||
|
|
||||||
- G101: Look for hard coded credentials
|
- G101: Look for hard coded credentials
|
||||||
|
@ -173,9 +173,10 @@ $ gosec -include=G101,G203,G401 ./...
|
||||||
# Run everything except for rule G303
|
# Run everything except for rule G303
|
||||||
$ gosec -exclude=G303 ./...
|
$ gosec -exclude=G303 ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
### CWE Mapping
|
### CWE Mapping
|
||||||
|
|
||||||
Every issue detected by `gosec` is mapped to a [CWE (Common Weakness Enumeration)](http://cwe.mitre.org/data/index.html) which describes in more generic terms the vulnerability. The exact mapping can be found [here](https://github.com/securego/gosec/blob/master/issue.go#L49).
|
Every issue detected by `gosec` is mapped to a [CWE (Common Weakness Enumeration)](http://cwe.mitre.org/data/index.html) which describes in more generic terms the vulnerability. The exact mapping can be found [here](https://github.com/securego/gosec/blob/master/issue.go#L50).
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
|
@ -197,6 +198,7 @@ A number of global settings can be provided in a configuration file as follows:
|
||||||
# Run with a global configuration file
|
# Run with a global configuration file
|
||||||
$ gosec -conf config.json .
|
$ gosec -conf config.json .
|
||||||
```
|
```
|
||||||
|
|
||||||
Also some rules accept configuration. For instance on rule `G104`, it is possible to define packages along with a list
|
Also some rules accept configuration. For instance on rule `G104`, it is possible to define packages along with a list
|
||||||
of functions which will be skipped when auditing the not checked errors:
|
of functions which will be skipped when auditing the not checked errors:
|
||||||
|
|
||||||
|
@ -307,6 +309,7 @@ $ gosec -fmt=json -out=results.json *.go
|
||||||
### Build
|
### Build
|
||||||
|
|
||||||
You can build the binary with:
|
You can build the binary with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
@ -314,11 +317,13 @@ make
|
||||||
### Note on Sarif Types Generation
|
### Note on Sarif Types Generation
|
||||||
|
|
||||||
Install the tool with :
|
Install the tool with :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go get -u github.com/a-h/generate/cmd/schema-generate
|
go get -u github.com/a-h/generate/cmd/schema-generate
|
||||||
```
|
```
|
||||||
|
|
||||||
Then generate the types with :
|
Then generate the types with :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
schema-generate -i sarif-schema-2.1.0.json -o mypath/types.go
|
schema-generate -i sarif-schema-2.1.0.json -o mypath/types.go
|
||||||
```
|
```
|
||||||
|
@ -326,10 +331,10 @@ schema-generate -i sarif-schema-2.1.0.json -o mypath/types.go
|
||||||
Most of the MarshallJSON/UnmarshalJSON are removed except the one for PropertyBag which is handy to inline the additionnal properties. The rest can be removed.
|
Most of the MarshallJSON/UnmarshalJSON are removed except the one for PropertyBag which is handy to inline the additionnal properties. The rest can be removed.
|
||||||
The URI,ID, UUID, GUID were renamed so it fits the Golang convention defined [here](https://github.com/golang/lint/blob/master/lint.go#L700)
|
The URI,ID, UUID, GUID were renamed so it fits the Golang convention defined [here](https://github.com/golang/lint/blob/master/lint.go#L700)
|
||||||
|
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
You can run all unit tests using:
|
You can run all unit tests using:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make test
|
make test
|
||||||
```
|
```
|
||||||
|
@ -360,6 +365,7 @@ into a volume as follows:
|
||||||
```bash
|
```bash
|
||||||
docker run --rm -it -w /<PROJECT>/ -v <YOUR PROJECT PATH>/<PROJECT>:/<PROJECT> securego/gosec /<PROJECT>/...
|
docker run --rm -it -w /<PROJECT>/ -v <YOUR PROJECT PATH>/<PROJECT>:/<PROJECT> securego/gosec /<PROJECT>/...
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** the current working directory needs to be set with `-w` option in order to get successfully resolved the dependencies from go module file
|
**Note:** the current working directory needs to be set with `-w` option in order to get successfully resolved the dependencies from go module file
|
||||||
|
|
||||||
### Generate TLS rule
|
### Generate TLS rule
|
||||||
|
|
|
@ -17,7 +17,7 @@ var defaultIssue = gosec.Issue{
|
||||||
Confidence: gosec.High,
|
Confidence: gosec.High,
|
||||||
Severity: gosec.High,
|
Severity: gosec.High,
|
||||||
Code: "1: testcode",
|
Code: "1: testcode",
|
||||||
Cwe: gosec.GetCwe("G101"),
|
Cwe: gosec.GetCweByRule("G101"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func createIssue() gosec.Issue {
|
func createIssue() gosec.Issue {
|
||||||
|
|
10
cwe/data.go
10
cwe/data.go
|
@ -1,6 +1,6 @@
|
||||||
package cwe
|
package cwe
|
||||||
|
|
||||||
var data = map[string]Weakness{
|
var data = map[string]*Weakness{
|
||||||
"118": {
|
"118": {
|
||||||
ID: "118",
|
ID: "118",
|
||||||
Description: "The software does not restrict or incorrectly restricts operations within the boundaries of a resource that is accessed using an index or pointer, such as memory or files.",
|
Description: "The software does not restrict or incorrectly restricts operations within the boundaries of a resource that is accessed using an index or pointer, such as memory or files.",
|
||||||
|
@ -104,6 +104,10 @@ var data = map[string]Weakness{
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get Retrieves a CWE weakness by it's id
|
//Get Retrieves a CWE weakness by it's id
|
||||||
func Get(id string) Weakness {
|
func Get(id string) *Weakness {
|
||||||
return data[id]
|
weakness, ok := data[id]
|
||||||
|
if ok && weakness != nil {
|
||||||
|
return weakness
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
30
cwe/types.go
30
cwe/types.go
|
@ -1,9 +1,17 @@
|
||||||
package cwe
|
package cwe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
//URL is the base URL for CWE definitions
|
||||||
|
URL = "https://cwe.mitre.org/data/definitions/"
|
||||||
|
//Acronym is the acronym of CWE
|
||||||
|
Acronym = "CWE"
|
||||||
|
)
|
||||||
|
|
||||||
// Weakness defines a CWE weakness based on http://cwe.mitre.org/data/xsd/cwe_schema_v6.4.xsd
|
// Weakness defines a CWE weakness based on http://cwe.mitre.org/data/xsd/cwe_schema_v6.4.xsd
|
||||||
type Weakness struct {
|
type Weakness struct {
|
||||||
ID string
|
ID string
|
||||||
|
@ -11,7 +19,23 @@ type Weakness struct {
|
||||||
Description string
|
Description string
|
||||||
}
|
}
|
||||||
|
|
||||||
//URL Expose the CWE URL
|
//SprintURL format the CWE URL
|
||||||
func (w *Weakness) URL() string {
|
func (w *Weakness) SprintURL() string {
|
||||||
return fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", w.ID)
|
return fmt.Sprintf("%s%s.html", URL, w.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
//SprintID format the CWE ID
|
||||||
|
func (w *Weakness) SprintID() string {
|
||||||
|
return fmt.Sprintf("%s-%s", Acronym, w.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
//MarshalJSON print only id and URL
|
||||||
|
func (w *Weakness) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(&struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}{
|
||||||
|
ID: w.ID,
|
||||||
|
URL: w.SprintURL(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
85
issue.go
85
issue.go
|
@ -19,6 +19,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/securego/gosec/v2/cwe"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"os"
|
"os"
|
||||||
|
@ -41,56 +42,54 @@ const (
|
||||||
// the beginning and after the end of a code snippet
|
// the beginning and after the end of a code snippet
|
||||||
const SnippetOffset = 1
|
const SnippetOffset = 1
|
||||||
|
|
||||||
// Cwe id and url
|
// GetCweByRule retrieves a cwe weakness for a given RuleID
|
||||||
type Cwe struct {
|
func GetCweByRule(id string) *cwe.Weakness {
|
||||||
ID string
|
cweID, ok := ruleToCWE[id]
|
||||||
URL string
|
if ok && cweID != "" {
|
||||||
|
return cwe.Get(cweID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCwe creates a cwe object for a given RuleID
|
// ruleToCWE maps gosec rules to CWEs
|
||||||
func GetCwe(id string) Cwe {
|
var ruleToCWE = map[string]string{
|
||||||
return Cwe{ID: id, URL: fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", id)}
|
"G101": "798",
|
||||||
}
|
"G102": "200",
|
||||||
|
"G103": "242",
|
||||||
// IssueToCWE maps gosec rules to CWEs
|
"G104": "703",
|
||||||
var IssueToCWE = map[string]Cwe{
|
"G106": "322",
|
||||||
"G101": GetCwe("798"),
|
"G107": "88",
|
||||||
"G102": GetCwe("200"),
|
"G108": "200",
|
||||||
"G103": GetCwe("242"),
|
"G109": "190",
|
||||||
"G104": GetCwe("703"),
|
"G110": "409",
|
||||||
"G106": GetCwe("322"),
|
"G201": "89",
|
||||||
"G107": GetCwe("88"),
|
"G202": "89",
|
||||||
"G108": GetCwe("200"),
|
"G203": "79",
|
||||||
"G109": GetCwe("190"),
|
"G204": "78",
|
||||||
"G110": GetCwe("409"),
|
"G301": "276",
|
||||||
"G201": GetCwe("89"),
|
"G302": "276",
|
||||||
"G202": GetCwe("89"),
|
"G303": "377",
|
||||||
"G203": GetCwe("79"),
|
"G304": "22",
|
||||||
"G204": GetCwe("78"),
|
"G305": "22",
|
||||||
"G301": GetCwe("276"),
|
"G306": "276",
|
||||||
"G302": GetCwe("276"),
|
"G307": "703",
|
||||||
"G303": GetCwe("377"),
|
"G401": "326",
|
||||||
"G304": GetCwe("22"),
|
"G402": "295",
|
||||||
"G305": GetCwe("22"),
|
"G403": "310",
|
||||||
"G306": GetCwe("276"),
|
"G404": "338",
|
||||||
"G307": GetCwe("703"),
|
"G501": "327",
|
||||||
"G401": GetCwe("326"),
|
"G502": "327",
|
||||||
"G402": GetCwe("295"),
|
"G503": "327",
|
||||||
"G403": GetCwe("310"),
|
"G504": "327",
|
||||||
"G404": GetCwe("338"),
|
"G505": "327",
|
||||||
"G501": GetCwe("327"),
|
"G601": "118",
|
||||||
"G502": GetCwe("327"),
|
|
||||||
"G503": GetCwe("327"),
|
|
||||||
"G504": GetCwe("327"),
|
|
||||||
"G505": GetCwe("327"),
|
|
||||||
"G601": GetCwe("118"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue is returned by a gosec rule if it discovers an issue with the scanned code.
|
// Issue is returned by a gosec rule if it discovers an issue with the scanned code.
|
||||||
type Issue struct {
|
type Issue struct {
|
||||||
Severity Score `json:"severity"` // issue severity (how problematic it is)
|
Severity Score `json:"severity"` // issue severity (how problematic it is)
|
||||||
Confidence Score `json:"confidence"` // issue confidence (how sure we are we found it)
|
Confidence Score `json:"confidence"` // issue confidence (how sure we are we found it)
|
||||||
Cwe Cwe `json:"cwe"` // Cwe associated with RuleID
|
Cwe *cwe.Weakness `json:"cwe"` // Cwe associated with RuleID
|
||||||
RuleID string `json:"rule_id"` // Human readable explanation
|
RuleID string `json:"rule_id"` // Human readable explanation
|
||||||
What string `json:"details"` // Human readable explanation
|
What string `json:"details"` // Human readable explanation
|
||||||
File string `json:"file"` // File name we found it in
|
File string `json:"file"` // File name we found it in
|
||||||
|
@ -196,6 +195,6 @@ func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score,
|
||||||
Confidence: confidence,
|
Confidence: confidence,
|
||||||
Severity: severity,
|
Severity: severity,
|
||||||
Code: code,
|
Code: code,
|
||||||
Cwe: IssueToCWE[ruleID],
|
Cwe: GetCweByRule(ruleID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ var _ = Describe("Issue", func() {
|
||||||
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.Col).Should(Equal("16"))
|
||||||
Expect(issue.Cwe.ID).Should(Equal(""))
|
Expect(issue.Cwe).Should(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should return an error if specific context is not able to be obtained", func() {
|
It("should return an error if specific context is not able to be obtained", func() {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package csv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"fmt"
|
|
||||||
"github.com/securego/gosec/v2/report/core"
|
"github.com/securego/gosec/v2/report/core"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
@ -19,7 +18,7 @@ func WriteReport(w io.Writer, data *core.ReportInfo) error {
|
||||||
issue.Severity.String(),
|
issue.Severity.String(),
|
||||||
issue.Confidence.String(),
|
issue.Confidence.String(),
|
||||||
issue.Code,
|
issue.Code,
|
||||||
fmt.Sprintf("CWE-%s", issue.Cwe.ID),
|
issue.Cwe.SprintID(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -9,6 +9,7 @@ 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/cwe"
|
||||||
"github.com/securego/gosec/v2/report/core"
|
"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"
|
||||||
|
@ -16,13 +17,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func createIssueWithFileWhat(file, what string) *gosec.Issue {
|
func createIssueWithFileWhat(file, what string) *gosec.Issue {
|
||||||
issue := createIssue("i1", gosec.GetCwe("G101"))
|
issue := createIssue("i1", gosec.GetCweByRule("G101"))
|
||||||
issue.File = file
|
issue.File = file
|
||||||
issue.What = what
|
issue.What = what
|
||||||
return &issue
|
return &issue
|
||||||
}
|
}
|
||||||
|
|
||||||
func createIssue(ruleID string, cwe gosec.Cwe) gosec.Issue {
|
func createIssue(ruleID string, weakness *cwe.Weakness) gosec.Issue {
|
||||||
return gosec.Issue{
|
return gosec.Issue{
|
||||||
File: "/home/src/project/test.go",
|
File: "/home/src/project/test.go",
|
||||||
Line: "1",
|
Line: "1",
|
||||||
|
@ -32,12 +33,12 @@ func createIssue(ruleID string, cwe gosec.Cwe) gosec.Issue {
|
||||||
Confidence: gosec.High,
|
Confidence: gosec.High,
|
||||||
Severity: gosec.High,
|
Severity: gosec.High,
|
||||||
Code: "1: testcode",
|
Code: "1: testcode",
|
||||||
Cwe: cwe,
|
Cwe: weakness,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createReportInfo(rule string, cwe gosec.Cwe) core.ReportInfo {
|
func createReportInfo(rule string, weakness *cwe.Weakness) core.ReportInfo {
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, weakness)
|
||||||
metrics := gosec.Metrics{}
|
metrics := gosec.Metrics{}
|
||||||
return core.ReportInfo{
|
return core.ReportInfo{
|
||||||
Errors: map[string][]gosec.Error{},
|
Errors: map[string][]gosec.Error{},
|
||||||
|
@ -284,7 +285,7 @@ var _ = Describe("Formatter", func() {
|
||||||
|
|
||||||
It("csv formatted report should contain the CWE mapping", func() {
|
It("csv formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
@ -298,7 +299,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("xml formatted report should contain the CWE mapping", func() {
|
It("xml formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
@ -312,7 +313,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("json formatted report should contain the CWE mapping", func() {
|
It("json formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
@ -332,7 +333,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("html formatted report should contain the CWE mapping", func() {
|
It("html formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
@ -352,7 +353,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("yaml formatted report should contain the CWE mapping", func() {
|
It("yaml formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
@ -372,7 +373,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("junit-xml formatted report should contain the CWE mapping", func() {
|
It("junit-xml formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
@ -392,7 +393,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("text formatted report should contain the CWE mapping", func() {
|
It("text formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
@ -412,7 +413,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("sonarqube formatted report shouldn't contain the CWE mapping", func() {
|
It("sonarqube formatted report shouldn't contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
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)
|
||||||
|
@ -432,7 +433,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("golint formatted report should contain the CWE mapping", func() {
|
It("golint formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
@ -446,7 +447,7 @@ var _ = Describe("Formatter", func() {
|
||||||
})
|
})
|
||||||
It("sarif formatted report should contain the CWE mapping", func() {
|
It("sarif formatted report should contain the CWE mapping", func() {
|
||||||
for _, rule := range grules {
|
for _, rule := range grules {
|
||||||
cwe := gosec.IssueToCWE[rule]
|
cwe := gosec.GetCweByRule(rule)
|
||||||
issue := createIssue(rule, cwe)
|
issue := createIssue(rule, cwe)
|
||||||
error := map[string][]gosec.Error{}
|
error := map[string][]gosec.Error{}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ func WriteReport(w io.Writer, data *core.ReportInfo) error {
|
||||||
for _, issue := range data.Issues {
|
for _, issue := range data.Issues {
|
||||||
what := issue.What
|
what := issue.What
|
||||||
if issue.Cwe.ID != "" {
|
if issue.Cwe.ID != "" {
|
||||||
what = fmt.Sprintf("[CWE-%s] %s", issue.Cwe.ID, issue.What)
|
what = fmt.Sprintf("[%s] %s", issue.Cwe.SprintID(), issue.What)
|
||||||
}
|
}
|
||||||
|
|
||||||
// issue.Line uses "start-end" format for multiple line detection.
|
// issue.Line uses "start-end" format for multiple line detection.
|
||||||
|
|
|
@ -19,7 +19,6 @@ const (
|
||||||
sarifNote = sarifLevel("note")
|
sarifNote = sarifLevel("note")
|
||||||
sarifWarning = sarifLevel("warning")
|
sarifWarning = sarifLevel("warning")
|
||||||
sarifError = sarifLevel("error")
|
sarifError = sarifLevel("error")
|
||||||
cweAcronym = "CWE"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//GenerateReport Convert a gosec report to a Sarif Report
|
//GenerateReport Convert a gosec report to a Sarif Report
|
||||||
|
@ -36,7 +35,7 @@ func GenerateReport(rootPaths []string, data *core.ReportInfo) (*Report, error)
|
||||||
|
|
||||||
results := []*Result{}
|
results := []*Result{}
|
||||||
taxa := make([]*ReportingDescriptor, 0)
|
taxa := make([]*ReportingDescriptor, 0)
|
||||||
weaknesses := make(map[string]cwe.Weakness)
|
weaknesses := make(map[string]*cwe.Weakness)
|
||||||
|
|
||||||
for _, issue := range data.Issues {
|
for _, issue := range data.Issues {
|
||||||
_, ok := weaknesses[issue.Cwe.ID]
|
_, ok := weaknesses[issue.Cwe.ID]
|
||||||
|
@ -117,18 +116,18 @@ func parseSarifRule(issue *gosec.Issue) *ReportingDescriptor {
|
||||||
Level: getSarifLevel(issue.Severity.String()),
|
Level: getSarifLevel(issue.Severity.String()),
|
||||||
},
|
},
|
||||||
Relationships: []*ReportingDescriptorRelationship{
|
Relationships: []*ReportingDescriptorRelationship{
|
||||||
buildSarifReportingDescriptorRelationship(issue.Cwe.ID),
|
buildSarifReportingDescriptorRelationship(issue.Cwe),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildSarifReportingDescriptorRelationship(weaknessID string) *ReportingDescriptorRelationship {
|
func buildSarifReportingDescriptorRelationship(weakness *cwe.Weakness) *ReportingDescriptorRelationship {
|
||||||
return &ReportingDescriptorRelationship{
|
return &ReportingDescriptorRelationship{
|
||||||
Target: &ReportingDescriptorReference{
|
Target: &ReportingDescriptorReference{
|
||||||
ID: weaknessID,
|
ID: weakness.ID,
|
||||||
GUID: uuid3(cweAcronym + weaknessID),
|
GUID: uuid3(weakness.SprintID()),
|
||||||
ToolComponent: &ToolComponentReference{
|
ToolComponent: &ToolComponentReference{
|
||||||
Name: cweAcronym,
|
Name: cwe.Acronym,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Kinds: []string{"superset"},
|
Kinds: []string{"superset"},
|
||||||
|
@ -149,7 +148,7 @@ func buildSarifTaxonomies(taxa []*ReportingDescriptor) []*ToolComponent {
|
||||||
|
|
||||||
func buildCWETaxonomy(version string, taxa []*ReportingDescriptor) *ToolComponent {
|
func buildCWETaxonomy(version string, taxa []*ReportingDescriptor) *ToolComponent {
|
||||||
return &ToolComponent{
|
return &ToolComponent{
|
||||||
Name: cweAcronym,
|
Name: cwe.Acronym,
|
||||||
Version: version,
|
Version: version,
|
||||||
ReleaseDateUtc: "2021-03-15",
|
ReleaseDateUtc: "2021-03-15",
|
||||||
InformationURI: fmt.Sprintf("https://cwe.mitre.org/data/published/cwe_v%s.pdf/", version),
|
InformationURI: fmt.Sprintf("https://cwe.mitre.org/data/published/cwe_v%s.pdf/", version),
|
||||||
|
@ -158,19 +157,19 @@ func buildCWETaxonomy(version string, taxa []*ReportingDescriptor) *ToolComponen
|
||||||
ShortDescription: &MultiformatMessageString{
|
ShortDescription: &MultiformatMessageString{
|
||||||
Text: "The MITRE Common Weakness Enumeration",
|
Text: "The MITRE Common Weakness Enumeration",
|
||||||
},
|
},
|
||||||
GUID: uuid3(cweAcronym),
|
GUID: uuid3(cwe.Acronym),
|
||||||
IsComprehensive: true,
|
IsComprehensive: true,
|
||||||
MinimumRequiredLocalizedDataSemanticVersion: version,
|
MinimumRequiredLocalizedDataSemanticVersion: version,
|
||||||
Taxa: taxa,
|
Taxa: taxa,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
Name: weakness.Name,
|
||||||
GUID: uuid3(cweAcronym + weakness.ID),
|
GUID: uuid3(weakness.SprintID()),
|
||||||
HelpURI: weakness.URL(),
|
HelpURI: weakness.SprintURL(),
|
||||||
ShortDescription: &MultiformatMessageString{
|
ShortDescription: &MultiformatMessageString{
|
||||||
Text: weakness.Description,
|
Text: weakness.Description,
|
||||||
},
|
},
|
||||||
|
@ -189,7 +188,7 @@ func buildSarifDriver(rules []*ReportingDescriptor) *ToolComponent {
|
||||||
Name: "gosec",
|
Name: "gosec",
|
||||||
Version: gosecVersion,
|
Version: gosecVersion,
|
||||||
SupportedTaxonomies: []*ToolComponentReference{
|
SupportedTaxonomies: []*ToolComponentReference{
|
||||||
{Name: cweAcronym, GUID: uuid3(cweAcronym)},
|
{Name: cwe.Acronym, GUID: uuid3(cwe.Acronym)},
|
||||||
},
|
},
|
||||||
InformationURI: "https://github.com/securego/gosec/",
|
InformationURI: "https://github.com/securego/gosec/",
|
||||||
Rules: rules,
|
Rules: rules,
|
||||||
|
|
|
@ -8,7 +8,7 @@ Golang errors in file: [{{ $filePath }}]:
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{ range $index, $issue := .Issues }}
|
{{ range $index, $issue := .Issues }}
|
||||||
[{{ highlight $issue.FileLocation $issue.Severity }}] - {{ $issue.RuleID }} (CWE-{{ $issue.Cwe.ID }}): {{ $issue.What }} (Confidence: {{ $issue.Confidence}}, Severity: {{ $issue.Severity }})
|
[{{ highlight $issue.FileLocation $issue.Severity }}] - {{ $issue.RuleID }} ({{ $issue.Cwe.SprintID }}): {{ $issue.What }} (Confidence: {{ $issue.Confidence}}, Severity: {{ $issue.Severity }})
|
||||||
{{ printCode $issue }}
|
{{ printCode $issue }}
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
Loading…
Reference in a new issue