From 5729ad6026bbe49eb3f570b54cb430265bf180fb Mon Sep 17 00:00:00 2001 From: segatomo Date: Tue, 3 Mar 2020 17:33:06 +0900 Subject: [PATCH] Add CWE Top25 and SANS Top25 (#925) * add top25 rank * add CweTop25 and SansTop25 * fix report * add cwetop25 and sanstop25 url * fix condition branch * fix condition branch --- cwe/cwe.go | 33 +++++++++++++++++++++++++++++++++ cwe/sans.go | 33 +++++++++++++++++++++++++++++++++ models/scanresults.go | 26 ++++++++++++++++++++++---- report/report.go | 12 ++++++++++++ report/slack.go | 16 +++++++++++++--- report/util.go | 24 ++++++++++++++++++++++-- 6 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 cwe/cwe.go create mode 100644 cwe/sans.go diff --git a/cwe/cwe.go b/cwe/cwe.go new file mode 100644 index 00000000..4bf42355 --- /dev/null +++ b/cwe/cwe.go @@ -0,0 +1,33 @@ +package cwe + +// CweTopTwentyfive2019 has CWE-ID in CWE Top 25 +var CweTopTwentyfive2019 = map[string]string{ + "119": "1", + "79": "2", + "20": "3", + "200": "4", + "125": "5", + "89": "6", + "416": "7", + "190": "8", + "352": "9", + "22": "10", + "78": "11", + "787": "12", + "287": "13", + "476": "14", + "732": "16", + "434": "16", + "611": "17", + "94": "18", + "798": "19", + "400": "20", + "772": "21", + "426": "22", + "502": "23", + "269": "24", + "295": "25", +} + +// CweTopTwentyfive2019URL has CWE Top25 links +var CweTopTwentyfive2019URL = "https://cwe.mitre.org/top25/archive/2019/2019_cwe_top25.html" diff --git a/cwe/sans.go b/cwe/sans.go new file mode 100644 index 00000000..083f1ae7 --- /dev/null +++ b/cwe/sans.go @@ -0,0 +1,33 @@ +package cwe + +// SansTopTwentyfive has CWE-ID in CWE/SANS Top 25 +var SansTopTwentyfive = map[string]string{ + "89": "1", + "78": "2", + "120": "3", + "79": "4", + "306": "5", + "862": "6", + "798": "7", + "311": "8", + "434": "9", + "807": "10", + "250": "11", + "352": "12", + "22": "13", + "494": "14", + "863": "15", + "829": "16", + "732": "17", + "676": "18", + "327": "19", + "131": "20", + "307": "21", + "601": "22", + "134": "23", + "190": "24", + "759": "25", +} + +// SansTopTwentyfiveURL +var SansTopTwentyfiveURL = "https://www.sans.org/top25-software-errors/" diff --git a/models/scanresults.go b/models/scanresults.go index b97eadf9..dcdc9ebf 100644 --- a/models/scanresults.go +++ b/models/scanresults.go @@ -62,7 +62,7 @@ type ScanResult struct { type CweDict map[string]CweDictEntry // Get the name, url, top10URL for the specified cweID, lang -func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string) { +func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL, cweTop25Rank, cweTop25URL, sansTop25Rank, sansTop25URL string) { cweNum := strings.TrimPrefix(cweID, "CWE-") switch config.Conf.Lang { case "ja": @@ -70,6 +70,14 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string) top10Rank = dict.OwaspTopTen2017 top10URL = cwe.OwaspTopTen2017GitHubURLJa[dict.OwaspTopTen2017] } + if dict, ok := c[cweNum]; ok && dict.CweTopTwentyfive2019 != "" { + cweTop25Rank = dict.CweTopTwentyfive2019 + cweTop25URL = cwe.CweTopTwentyfive2019URL + } + if dict, ok := c[cweNum]; ok && dict.SansTopTwentyfive != "" { + sansTop25Rank = dict.SansTopTwentyfive + sansTop25URL = cwe.SansTopTwentyfiveURL + } if dict, ok := cwe.CweDictJa[cweNum]; ok { name = dict.Name url = fmt.Sprintf("http://jvndb.jvn.jp/ja/cwe/%s.html", cweID) @@ -84,6 +92,14 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string) top10Rank = dict.OwaspTopTen2017 top10URL = cwe.OwaspTopTen2017GitHubURLEn[dict.OwaspTopTen2017] } + if dict, ok := c[cweNum]; ok && dict.CweTopTwentyfive2019 != "" { + cweTop25Rank = dict.CweTopTwentyfive2019 + cweTop25URL = cwe.CweTopTwentyfive2019URL + } + if dict, ok := c[cweNum]; ok && dict.SansTopTwentyfive != "" { + sansTop25Rank = dict.SansTopTwentyfive + sansTop25URL = cwe.SansTopTwentyfiveURL + } url = fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", cweID) if dict, ok := cwe.CweDictEn[cweNum]; ok { name = dict.Name @@ -94,9 +110,11 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string) // CweDictEntry is a entry of CWE type CweDictEntry struct { - En *cwe.Cwe `json:"en,omitempty"` - Ja *cwe.Cwe `json:"ja,omitempty"` - OwaspTopTen2017 string `json:"owaspTopTen2017"` + En *cwe.Cwe `json:"en,omitempty"` + Ja *cwe.Cwe `json:"ja,omitempty"` + OwaspTopTen2017 string `json:"owaspTopTen2017"` + CweTopTwentyfive2019 string `json:"cweTopTwentyfive2019"` + SansTopTwentyfive string `json:"sansTopTwentyfive"` } // Kernel has the Release, version and whether need restart diff --git a/report/report.go b/report/report.go index 8e46b7c2..1c82786a 100644 --- a/report/report.go +++ b/report/report.go @@ -467,6 +467,12 @@ func fillCweDict(r *models.ScanResult) { if rank, ok := cwe.OwaspTopTen2017[id]; ok { entry.OwaspTopTen2017 = rank } + if rank, ok := cwe.CweTopTwentyfive2019[id]; ok { + entry.CweTopTwentyfive2019 = rank + } + if rank, ok := cwe.SansTopTwentyfive[id]; ok { + entry.SansTopTwentyfive = rank + } entry.En = &e } else { util.Log.Debugf("CWE-ID %s is not found in English CWE Dict", id) @@ -478,6 +484,12 @@ func fillCweDict(r *models.ScanResult) { if rank, ok := cwe.OwaspTopTen2017[id]; ok { entry.OwaspTopTen2017 = rank } + if rank, ok := cwe.CweTopTwentyfive2019[id]; ok { + entry.CweTopTwentyfive2019 = rank + } + if rank, ok := cwe.SansTopTwentyfive[id]; ok { + entry.SansTopTwentyfive = rank + } entry.Ja = &e } else { util.Log.Debugf("CWE-ID %s is not found in Japanese CWE Dict", id) diff --git a/report/slack.go b/report/slack.go index 0a11f364..9f0a2668 100644 --- a/report/slack.go +++ b/report/slack.go @@ -329,14 +329,24 @@ func attachmentText(vinfo models.VulnInfo, osFamily string, cweDict map[string]m func cweIDs(vinfo models.VulnInfo, osFamily string, cweDict models.CweDict) string { links := []string{} for _, c := range vinfo.CveContents.UniqCweIDs(osFamily) { - name, url, top10Rank, top10URL := cweDict.Get(c.Value, osFamily) + name, url, top10Rank, top10URL, cweTop25Rank, cweTop25URL, sansTop25Rank, sansTop25URL := cweDict.Get(c.Value, osFamily) line := "" if top10Rank != "" { line = fmt.Sprintf("<%s|[OWASP Top %s]>", top10URL, top10Rank) } - links = append(links, fmt.Sprintf("%s <%s|%s>: %s", - line, url, c.Value, name)) + if cweTop25Rank != "" { + line = fmt.Sprintf("<%s|[CWE Top %s]>", + cweTop25URL, cweTop25Rank) + } + if sansTop25Rank != "" { + line = fmt.Sprintf("<%s|[CWE/SANS Top %s]>", + sansTop25URL, sansTop25Rank) + } + if top10Rank == "" && cweTop25Rank == "" && sansTop25Rank == "" { + links = append(links, fmt.Sprintf("%s <%s|%s>: %s", + line, url, c.Value, name)) + } } return strings.Join(links, "\n") } diff --git a/report/util.go b/report/util.go index 18148549..abdc5d56 100644 --- a/report/util.go +++ b/report/util.go @@ -217,14 +217,28 @@ No CVE-IDs are found in updatable packages. } cweURLs, top10URLs := []string{}, []string{} + cweTop25URLs, sansTop25URLs := []string{}, []string{} for _, v := range vuln.CveContents.UniqCweIDs(r.Family) { - name, url, top10Rank, top10URL := r.CweDict.Get(v.Value, r.Lang) + name, url, top10Rank, top10URL, cweTop25Rank, cweTop25URL, sansTop25Rank, sansTop25URL := r.CweDict.Get(v.Value, r.Lang) if top10Rank != "" { data = append(data, []string{"CWE", fmt.Sprintf("[OWASP Top%s] %s: %s (%s)", top10Rank, v.Value, name, v.Type)}) top10URLs = append(top10URLs, top10URL) - } else { + } + if cweTop25Rank != "" { + data = append(data, []string{"CWE", + fmt.Sprintf("[CWE Top%s] %s: %s (%s)", + cweTop25Rank, v.Value, name, v.Type)}) + cweTop25URLs = append(cweTop25URLs, cweTop25URL) + } + if sansTop25Rank != "" { + data = append(data, []string{"CWE", + fmt.Sprintf("[CWE/SANS Top%s] %s: %s (%s)", + sansTop25Rank, v.Value, name, v.Type)}) + sansTop25URLs = append(sansTop25URLs, sansTop25URL) + } + if top10Rank == "" && cweTop25Rank == "" && sansTop25Rank == "" { data = append(data, []string{"CWE", fmt.Sprintf("%s: %s (%s)", v.Value, name, v.Type)}) } @@ -309,6 +323,12 @@ No CVE-IDs are found in updatable packages. for _, url := range top10URLs { data = append(data, []string{"OWASP Top10", url}) } + if len(cweTop25URLs) != 0 { + data = append(data, []string{"CWE Top25", cweTop25URLs[0]}) + } + if len(sansTop25URLs) != 0 { + data = append(data, []string{"SANS/CWE Top25", sansTop25URLs[0]}) + } for _, alert := range vuln.AlertDict.Ja { data = append(data, []string{"JPCERT Alert", alert.URL})