Skip to content

Commit c4f5932

Browse files
authored
Refactor : Replace Cwe with cwe.Weakness
1 parent ddfa253 commit c4f5932

File tree

11 files changed

+128
-96
lines changed

11 files changed

+128
-96
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ echo "<check sum from the check sum file> gosec_vX.Y.Z_OS.tar.gz" | sha256sum -
4747

4848
gosec --help
4949
```
50+
5051
### GitHub Action
5152

5253
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
123124
run against the supplied input files. To recursively scan from the current
124125
directory you can supply `./...` as the input argument.
125126

126-
127127
### Available rules
128128

129129
- G101: Look for hard coded credentials
@@ -173,9 +173,10 @@ $ gosec -include=G101,G203,G401 ./...
173173
# Run everything except for rule G303
174174
$ gosec -exclude=G303 ./...
175175
```
176+
176177
### CWE Mapping
177178

178-
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).
179+
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).
179180

180181
### Configuration
181182

@@ -197,6 +198,7 @@ A number of global settings can be provided in a configuration file as follows:
197198
# Run with a global configuration file
198199
$ gosec -conf config.json .
199200
```
201+
200202
Also some rules accept configuration. For instance on rule `G104`, it is possible to define packages along with a list
201203
of functions which will be skipped when auditing the not checked errors:
202204

@@ -224,7 +226,7 @@ You can also configure the hard-coded credentials rule `G101` with additional pa
224226

225227
### Dependencies
226228

227-
gosec will fetch automatically the dependencies of the code which is being analyzed when go module is turned on (e.g.` GO111MODULE=on`). If this is not the case,
229+
gosec will fetch automatically the dependencies of the code which is being analyzed when go module is turned on (e.g.`GO111MODULE=on`). If this is not the case,
228230
the dependencies need to be explicitly downloaded by running the `go get -d` command before the scan.
229231

230232
### Excluding test files and folders
@@ -307,29 +309,32 @@ $ gosec -fmt=json -out=results.json *.go
307309
### Build
308310

309311
You can build the binary with:
312+
310313
```bash
311314
make
312315
```
313316

314317
### Note on Sarif Types Generation
315318

316319
Install the tool with :
320+
317321
```bash
318322
go get -u github.com/a-h/generate/cmd/schema-generate
319323
```
320324

321325
Then generate the types with :
326+
322327
```bash
323328
schema-generate -i sarif-schema-2.1.0.json -o mypath/types.go
324329
```
325330

326331
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.
327332
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)
328333

329-
330334
### Tests
331335

332336
You can run all unit tests using:
337+
333338
```bash
334339
make test
335340
```
@@ -360,7 +365,8 @@ into a volume as follows:
360365
```bash
361366
docker run --rm -it -w /<PROJECT>/ -v <YOUR PROJECT PATH>/<PROJECT>:/<PROJECT> securego/gosec /<PROJECT>/...
362367
```
363-
**Note:** the current working directory needs to be set with `-w` option in order to get successfully resolved the dependencies from go module file
368+
369+
**Note:** the current working directory needs to be set with `-w` option in order to get successfully resolved the dependencies from go module file
364370

365371
### Generate TLS rule
366372

cmd/gosec/sort_issues_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ var defaultIssue = gosec.Issue{
1717
Confidence: gosec.High,
1818
Severity: gosec.High,
1919
Code: "1: testcode",
20-
Cwe: gosec.GetCwe("G101"),
20+
Cwe: gosec.GetCweByRule("G101"),
2121
}
2222

2323
func createIssue() gosec.Issue {

cwe/data.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package cwe
22

3-
var data = map[string]Weakness{
3+
var data = map[string]*Weakness{
44
"118": {
55
ID: "118",
66
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{
104104
}
105105

106106
//Get Retrieves a CWE weakness by it's id
107-
func Get(id string) Weakness {
108-
return data[id]
107+
func Get(id string) *Weakness {
108+
weakness, ok := data[id]
109+
if ok && weakness != nil {
110+
return weakness
111+
}
112+
return nil
109113
}

cwe/types.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,41 @@
11
package cwe
22

33
import (
4+
"encoding/json"
45
"fmt"
56
)
67

8+
const (
9+
//URL is the base URL for CWE definitions
10+
URL = "https://cwe.mitre.org/data/definitions/"
11+
//Acronym is the acronym of CWE
12+
Acronym = "CWE"
13+
)
14+
715
// Weakness defines a CWE weakness based on http://cwe.mitre.org/data/xsd/cwe_schema_v6.4.xsd
816
type Weakness struct {
917
ID string
1018
Name string
1119
Description string
1220
}
1321

14-
//URL Expose the CWE URL
15-
func (w *Weakness) URL() string {
16-
return fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", w.ID)
22+
//SprintURL format the CWE URL
23+
func (w *Weakness) SprintURL() string {
24+
return fmt.Sprintf("%s%s.html", URL, w.ID)
25+
}
26+
27+
//SprintID format the CWE ID
28+
func (w *Weakness) SprintID() string {
29+
return fmt.Sprintf("%s-%s", Acronym, w.ID)
30+
}
31+
32+
//MarshalJSON print only id and URL
33+
func (w *Weakness) MarshalJSON() ([]byte, error) {
34+
return json.Marshal(&struct {
35+
ID string `json:"id"`
36+
URL string `json:"url"`
37+
}{
38+
ID: w.ID,
39+
URL: w.SprintURL(),
40+
})
1741
}

issue.go

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"bytes"
2020
"encoding/json"
2121
"fmt"
22+
"github.com/securego/gosec/v2/cwe"
2223
"go/ast"
2324
"go/token"
2425
"os"
@@ -41,62 +42,60 @@ const (
4142
// the beginning and after the end of a code snippet
4243
const SnippetOffset = 1
4344

44-
// Cwe id and url
45-
type Cwe struct {
46-
ID string
47-
URL string
48-
}
49-
50-
// GetCwe creates a cwe object for a given RuleID
51-
func GetCwe(id string) Cwe {
52-
return Cwe{ID: id, URL: fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", id)}
45+
// GetCweByRule retrieves a cwe weakness for a given RuleID
46+
func GetCweByRule(id string) *cwe.Weakness {
47+
cweID, ok := ruleToCWE[id]
48+
if ok && cweID != "" {
49+
return cwe.Get(cweID)
50+
}
51+
return nil
5352
}
5453

55-
// IssueToCWE maps gosec rules to CWEs
56-
var IssueToCWE = map[string]Cwe{
57-
"G101": GetCwe("798"),
58-
"G102": GetCwe("200"),
59-
"G103": GetCwe("242"),
60-
"G104": GetCwe("703"),
61-
"G106": GetCwe("322"),
62-
"G107": GetCwe("88"),
63-
"G108": GetCwe("200"),
64-
"G109": GetCwe("190"),
65-
"G110": GetCwe("409"),
66-
"G201": GetCwe("89"),
67-
"G202": GetCwe("89"),
68-
"G203": GetCwe("79"),
69-
"G204": GetCwe("78"),
70-
"G301": GetCwe("276"),
71-
"G302": GetCwe("276"),
72-
"G303": GetCwe("377"),
73-
"G304": GetCwe("22"),
74-
"G305": GetCwe("22"),
75-
"G306": GetCwe("276"),
76-
"G307": GetCwe("703"),
77-
"G401": GetCwe("326"),
78-
"G402": GetCwe("295"),
79-
"G403": GetCwe("310"),
80-
"G404": GetCwe("338"),
81-
"G501": GetCwe("327"),
82-
"G502": GetCwe("327"),
83-
"G503": GetCwe("327"),
84-
"G504": GetCwe("327"),
85-
"G505": GetCwe("327"),
86-
"G601": GetCwe("118"),
54+
// ruleToCWE maps gosec rules to CWEs
55+
var ruleToCWE = map[string]string{
56+
"G101": "798",
57+
"G102": "200",
58+
"G103": "242",
59+
"G104": "703",
60+
"G106": "322",
61+
"G107": "88",
62+
"G108": "200",
63+
"G109": "190",
64+
"G110": "409",
65+
"G201": "89",
66+
"G202": "89",
67+
"G203": "79",
68+
"G204": "78",
69+
"G301": "276",
70+
"G302": "276",
71+
"G303": "377",
72+
"G304": "22",
73+
"G305": "22",
74+
"G306": "276",
75+
"G307": "703",
76+
"G401": "326",
77+
"G402": "295",
78+
"G403": "310",
79+
"G404": "338",
80+
"G501": "327",
81+
"G502": "327",
82+
"G503": "327",
83+
"G504": "327",
84+
"G505": "327",
85+
"G601": "118",
8786
}
8887

8988
// Issue is returned by a gosec rule if it discovers an issue with the scanned code.
9089
type Issue struct {
91-
Severity Score `json:"severity"` // issue severity (how problematic it is)
92-
Confidence Score `json:"confidence"` // issue confidence (how sure we are we found it)
93-
Cwe Cwe `json:"cwe"` // Cwe associated with RuleID
94-
RuleID string `json:"rule_id"` // Human readable explanation
95-
What string `json:"details"` // Human readable explanation
96-
File string `json:"file"` // File name we found it in
97-
Code string `json:"code"` // Impacted code line
98-
Line string `json:"line"` // Line number in file
99-
Col string `json:"column"` // Column number in line
90+
Severity Score `json:"severity"` // issue severity (how problematic it is)
91+
Confidence Score `json:"confidence"` // issue confidence (how sure we are we found it)
92+
Cwe *cwe.Weakness `json:"cwe"` // Cwe associated with RuleID
93+
RuleID string `json:"rule_id"` // Human readable explanation
94+
What string `json:"details"` // Human readable explanation
95+
File string `json:"file"` // File name we found it in
96+
Code string `json:"code"` // Impacted code line
97+
Line string `json:"line"` // Line number in file
98+
Col string `json:"column"` // Column number in line
10099
}
101100

102101
// FileLocation point out the file path and line number in file
@@ -196,6 +195,6 @@ func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score,
196195
Confidence: confidence,
197196
Severity: severity,
198197
Code: code,
199-
Cwe: IssueToCWE[ruleID],
198+
Cwe: GetCweByRule(ruleID),
200199
}
201200
}

issue_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var _ = Describe("Issue", func() {
4242
Expect(issue.Code).Should(MatchRegexp(`"bar"`))
4343
Expect(issue.Line).Should(Equal("2"))
4444
Expect(issue.Col).Should(Equal("16"))
45-
Expect(issue.Cwe.ID).Should(Equal(""))
45+
Expect(issue.Cwe).Should(BeNil())
4646
})
4747

4848
It("should return an error if specific context is not able to be obtained", func() {

report/csv/writer.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package csv
22

33
import (
44
"encoding/csv"
5-
"fmt"
65
"github.com/securego/gosec/v2/report/core"
76
"io"
87
)
@@ -19,7 +18,7 @@ func WriteReport(w io.Writer, data *core.ReportInfo) error {
1918
issue.Severity.String(),
2019
issue.Confidence.String(),
2120
issue.Code,
22-
fmt.Sprintf("CWE-%s", issue.Cwe.ID),
21+
issue.Cwe.SprintID(),
2322
})
2423
if err != nil {
2524
return err

0 commit comments

Comments
 (0)