Skip to content

Commit 3adfbde

Browse files
authored
(feat) gosec parser: parse cwe_id and swap references if possible (#14581)
* Updates gosec parser.py to take cwe - changes the parser to take on CWE data when available - falls back to hardcoded url + rule_id when the above isn't present (latest gosec versions) * updates unittest files for gosec - adds cwe data * updates test_gosec_parser.py - adds cwe tests * updates gosec parser - fixes protection on cwe_id conversion - Added a protection on the cwe_id assignment via the integer convertion from string
1 parent 4934528 commit 3adfbde

3 files changed

Lines changed: 62 additions & 6 deletions

File tree

dojo/tools/gosec/parser.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def get_findings(self, filename, test):
2626
references = ""
2727
findingdetail = ""
2828
title = ""
29+
cwe_id = None
2930
filename = item.get("file")
3031
line = item.get("line")
3132
scanner_confidence = item.get("confidence")
@@ -40,11 +41,22 @@ def get_findings(self, filename, test):
4041
findingdetail += "```{}```".format(item["code"])
4142

4243
sev = item["severity"]
43-
# Best attempt at ongoing documentation provided by gosec, based on
44-
# rule id
45-
references = "https://securego.io/docs/rules/{}.html".format(
46-
item["rule_id"],
47-
).lower()
44+
45+
# Extract CWE information if available
46+
cwe_data = item.get("cwe", {})
47+
if cwe_data:
48+
cwe_id_str = cwe_data.get("id")
49+
if cwe_id_str:
50+
cwe_id = int(cwe_id_str) if cwe_id_str.isdigit() else None
51+
cwe_url = cwe_data.get("url")
52+
if cwe_url:
53+
references = cwe_url
54+
55+
# If no CWE URL, fall back to gosec rule documentation
56+
if not references:
57+
references = "https://securego.io/docs/rules/{}.html".format(
58+
item["rule_id"],
59+
).lower()
4860

4961
if scanner_confidence:
5062
# Assign integer value to confidence.
@@ -76,6 +88,7 @@ def get_findings(self, filename, test):
7688
references=references,
7789
file_path=filename,
7890
line=line,
91+
cwe=cwe_id,
7992
scanner_confidence=scanner_confidence,
8093
static_finding=True,
8194
)

unittests/scans/gosec/many_vulns.json

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
{
44
"severity": "LOW",
55
"confidence": "HIGH",
6+
"cwe": {
7+
"id": "252",
8+
"url": "https://cwe.mitre.org/data/definitions/252.html"
9+
},
610
"rule_id": "G104",
711
"details": "Errors unhandled.",
812
"file": "/vagrant/go/src/govwa/app.go",
@@ -12,6 +16,10 @@
1216
{
1317
"severity": "LOW",
1418
"confidence": "HIGH",
19+
"cwe": {
20+
"id": "252",
21+
"url": "https://cwe.mitre.org/data/definitions/252.html"
22+
},
1523
"rule_id": "G104",
1624
"details": "Errors unhandled.",
1725
"file": "/vagrant/go/src/govwa/setting/setting.go",
@@ -30,6 +38,10 @@
3038
{
3139
"severity": "MEDIUM",
3240
"confidence": "HIGH",
41+
"cwe": {
42+
"id": "327",
43+
"url": "https://cwe.mitre.org/data/definitions/327.html"
44+
},
3345
"rule_id": "G501",
3446
"details": "Blacklisted import crypto/md5: weak cryptographic primitive",
3547
"file": "/vagrant/go/src/govwa/user/user.go",
@@ -39,6 +51,10 @@
3951
{
4052
"severity": "MEDIUM",
4153
"confidence": "HIGH",
54+
"cwe": {
55+
"id": "327",
56+
"url": "https://cwe.mitre.org/data/definitions/327.html"
57+
},
4258
"rule_id": "G401",
4359
"details": "Use of weak cryptographic primitive",
4460
"file": "/vagrant/go/src/govwa/user/user.go",
@@ -84,6 +100,10 @@
84100
{
85101
"severity": "MEDIUM",
86102
"confidence": "LOW",
103+
"cwe": {
104+
"id": "79",
105+
"url": "https://cwe.mitre.org/data/definitions/79.html"
106+
},
87107
"rule_id": "G203",
88108
"details": "this method will not auto-escape HTML. Verify data is well formed.",
89109
"file": "/vagrant/go/src/govwa/util/template.go",
@@ -201,6 +221,10 @@
201221
{
202222
"severity": "MEDIUM",
203223
"confidence": "HIGH",
224+
"cwe": {
225+
"id": "89",
226+
"url": "https://cwe.mitre.org/data/definitions/89.html"
227+
},
204228
"rule_id": "G201",
205229
"details": "SQL string formatting",
206230
"file": "/vagrant/go/src/govwa/vulnerability/sqli/function.go",
@@ -259,4 +283,4 @@
259283
"nosec": 0,
260284
"found": 28
261285
}
262-
}
286+
}

unittests/tools/test_gosec_parser.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,26 @@ def test_parse_file_with_one_finding(self):
1010
parser = GosecParser()
1111
findings = parser.get_findings(testfile, Test())
1212
self.assertEqual(28, len(findings))
13+
14+
# Test first finding with CWE
1315
finding = findings[0]
1416
self.assertEqual("Low", finding.severity)
1517
self.assertEqual("/vagrant/go/src/govwa/app.go", finding.file_path)
1618
self.assertEqual(79, finding.line)
19+
self.assertEqual(252, finding.cwe)
20+
self.assertEqual("https://cwe.mitre.org/data/definitions/252.html", finding.references)
21+
22+
# Test finding without CWE (should fallback to gosec docs)
23+
finding_no_cwe = findings[2]
24+
self.assertIsNone(finding_no_cwe.cwe)
25+
self.assertEqual("https://securego.io/docs/rules/g104.html", finding_no_cwe.references)
26+
27+
# Test finding with different CWE
28+
finding_crypto = findings[3]
29+
self.assertEqual(327, finding_crypto.cwe)
30+
self.assertEqual("https://cwe.mitre.org/data/definitions/327.html", finding_crypto.references)
31+
32+
# Test SQL injection finding
33+
finding_sqli = findings[22]
34+
self.assertEqual(89, finding_sqli.cwe)
35+
self.assertEqual("https://cwe.mitre.org/data/definitions/89.html", finding_sqli.references)

0 commit comments

Comments
 (0)