Skip to content

Commit d8bff91

Browse files
authored
feat(detector/cve): support euvd (#2364)
1 parent 3f82b46 commit d8bff91

File tree

9 files changed

+275
-16
lines changed

9 files changed

+275
-16
lines changed

detector/detector.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ func DetectWordPressCves(r *models.ScanResult, wpCnf config.WpScanConf) error {
442442
return nil
443443
}
444444

445-
// FillCvesWithGoCVEDictionary fills CVE detail with NVD, VulnCheck, JVN, Fortinet, MITRE, Paloalto, Cisco
445+
// FillCvesWithGoCVEDictionary fills CVE detail with NVD, VulnCheck, JVN, EUVD, Fortinet, MITRE, Paloalto, Cisco
446446
func FillCvesWithGoCVEDictionary(r *models.ScanResult, cnf config.GoCveDictConf, logOpts logging.LogOpts) (err error) {
447447
cveIDs := []string{}
448448
for _, v := range r.ScannedCves {
@@ -468,6 +468,7 @@ func FillCvesWithGoCVEDictionary(r *models.ScanResult, cnf config.GoCveDictConf,
468468
nvds, exploits, mitigations := models.ConvertNvdToModel(d.CveID, d.Nvds)
469469
vulnchecks := models.ConvertVulncheckToModel(d.CveID, d.Vulnchecks)
470470
jvns := models.ConvertJvnToModel(d.CveID, d.Jvns)
471+
euvds := models.ConvertEuvdToModel(d.CveID, d.Euvds)
471472
fortinets := models.ConvertFortinetToModel(d.CveID, d.Fortinets)
472473
mitres := models.ConvertMitreToModel(d.CveID, d.Mitres)
473474
paloaltos := models.ConvertPaloaltoToModel(d.CveID, d.Paloaltos)
@@ -487,7 +488,7 @@ func FillCvesWithGoCVEDictionary(r *models.ScanResult, cnf config.GoCveDictConf,
487488
for _, con := range vulnchecks {
488489
vinfo.CveContents[con.Type] = append(vinfo.CveContents[con.Type], con)
489490
}
490-
for _, cons := range [][]models.CveContent{jvns, fortinets, paloaltos, ciscos} {
491+
for _, cons := range [][]models.CveContent{jvns, euvds, fortinets, paloaltos, ciscos} {
491492
for _, con := range cons {
492493
if !con.Empty() {
493494
if !slices.ContainsFunc(vinfo.CveContents[con.Type], func(e models.CveContent) bool {

detector/util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ func getMinusDiffCves(previous, current models.ScanResult) models.VulnInfos {
182182
}
183183

184184
func isCveInfoUpdated(cveID string, previous, current models.ScanResult) bool {
185-
cTypes := append([]models.CveContentType{models.Mitre, models.Nvd, models.Vulncheck, models.Jvn}, models.GetCveContentTypes(current.Family)...)
185+
cTypes := append([]models.CveContentType{models.Mitre, models.Nvd, models.Vulncheck, models.Jvn, models.Euvd}, models.GetCveContentTypes(current.Family)...)
186186

187187
prevLastModified := map[models.CveContentType][]time.Time{}
188188
preVinfo, ok := previous.ScannedCves[cveID]

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
github.com/gosnmp/gosnmp v1.42.1
3131
github.com/gosuri/uitable v0.0.4
3232
github.com/hashicorp/go-uuid v1.0.3
33-
github.com/hashicorp/go-version v1.7.0
33+
github.com/hashicorp/go-version v1.8.0
3434
github.com/jesseduffield/gocui v0.3.0
3535
github.com/k0kubun/pp v3.0.1+incompatible
3636
github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f
@@ -52,7 +52,7 @@ require (
5252
github.com/spdx/tools-golang v0.5.5
5353
github.com/spf13/cobra v1.10.1
5454
github.com/vulsio/go-cti v0.3.2
55-
github.com/vulsio/go-cve-dictionary v0.14.1-0.20251126061429-9de63913c5a6
55+
github.com/vulsio/go-cve-dictionary v0.14.1-0.20251129095104-e3e9f6c5bb88
5656
github.com/vulsio/go-exploitdb v0.6.2
5757
github.com/vulsio/go-kev v0.4.2
5858
github.com/vulsio/go-msfdb v0.4.2

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,8 @@ github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhE
502502
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
503503
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
504504
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
505-
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
506-
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
505+
github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
506+
github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
507507
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw=
508508
github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU=
509509
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
@@ -888,8 +888,8 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh
888888
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
889889
github.com/vulsio/go-cti v0.3.2 h1:GsFwl18oA0pxEz7lvdKRZcF6ygS6WjaEG4I9wtSMrwE=
890890
github.com/vulsio/go-cti v0.3.2/go.mod h1:38MJ5oV3yor6YKrMqq0HMydwSvOjlw2JK6fHuq9kYhQ=
891-
github.com/vulsio/go-cve-dictionary v0.14.1-0.20251126061429-9de63913c5a6 h1:GvlWL6M3P2VJXlRc7TV+os2U5dtfYmGeJA33cG+Ej1c=
892-
github.com/vulsio/go-cve-dictionary v0.14.1-0.20251126061429-9de63913c5a6/go.mod h1:ERpoGxo8icHzVTNGBagrnqdFHBUlzI20SSo0A+Yvd7w=
891+
github.com/vulsio/go-cve-dictionary v0.14.1-0.20251129095104-e3e9f6c5bb88 h1:HUv4RG3ZGa5LsxOHfpt2L17YbreVJEgsWDA8buJ3Xik=
892+
github.com/vulsio/go-cve-dictionary v0.14.1-0.20251129095104-e3e9f6c5bb88/go.mod h1:ERpoGxo8icHzVTNGBagrnqdFHBUlzI20SSo0A+Yvd7w=
893893
github.com/vulsio/go-exploitdb v0.6.2 h1:FtCXQCE/Rv7x1410aJxcpZRl5xOXRRm6ePlIxmdp6Tc=
894894
github.com/vulsio/go-exploitdb v0.6.2/go.mod h1:oAu9kwRZcBsmthgju1lupSX2V/MERNIVRgn5a28ldvc=
895895
github.com/vulsio/go-kev v0.4.2 h1:UHNTC7kElTg2e+vQsB4+wZ64TFYWFQ9ojHbx7FiKWz0=

models/cvecontents.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (v CveContents) PrimarySrcURLs(lang, myFamily, cveID string, confidences Co
5555
return
5656
}
5757

58-
for _, ctype := range append(append(CveContentTypes{Mitre, Nvd, Vulncheck, Jvn}, GetCveContentTypes(myFamily)...), GitHub) {
58+
for _, ctype := range append(append(CveContentTypes{Mitre, Nvd, Vulncheck, Jvn, Euvd}, GetCveContentTypes(myFamily)...), GitHub) {
5959
for _, cont := range v[ctype] {
6060
switch ctype {
6161
case Nvd, Vulncheck:
@@ -316,6 +316,8 @@ func NewCveContentType(name string) CveContentType {
316316
return Vulncheck
317317
case "jvn":
318318
return Jvn
319+
case "euvd":
320+
return Euvd
319321
case "redhat", "centos":
320322
return RedHat
321323
case "alma":
@@ -466,6 +468,9 @@ const (
466468
// Jvn is Jvn
467469
Jvn CveContentType = "jvn"
468470

471+
// Euvd is Euvd
472+
Euvd CveContentType = "euvd"
473+
469474
// Fortinet is Fortinet
470475
Fortinet CveContentType = "fortinet"
471476

@@ -638,6 +643,7 @@ var AllCveContetTypes = CveContentTypes{
638643
Nvd,
639644
Vulncheck,
640645
Jvn,
646+
Euvd,
641647
Fortinet,
642648
Paloalto,
643649
Cisco,

models/utils.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,79 @@ func ConvertJvnToModel(cveID string, jvns []cvedict.Jvn) []CveContent {
5454
return cves
5555
}
5656

57+
// ConvertEuvdToModel convert EUVD to CveContent
58+
func ConvertEuvdToModel(cveID string, euvds []cvedict.Euvd) []CveContent {
59+
cves := make([]CveContent, 0, len(euvds))
60+
for _, euvd := range euvds {
61+
refs := make([]Reference, 0, len(euvd.References))
62+
for _, r := range euvd.References {
63+
refs = append(refs, Reference{
64+
Link: r.Link,
65+
Source: r.Source,
66+
})
67+
}
68+
69+
cve := CveContent{
70+
Type: Euvd,
71+
CveID: cveID,
72+
Title: euvd.EuvdID,
73+
Summary: euvd.Description,
74+
SourceLink: fmt.Sprintf("https://euvd.enisa.europa.eu/vulnerability/%s", euvd.EuvdID),
75+
References: refs,
76+
Published: euvd.DatePublished,
77+
LastModified: euvd.DateUpdated,
78+
}
79+
80+
switch euvd.BaseScoreVersion {
81+
case "2.0":
82+
cve.Cvss2Score = euvd.BaseScore
83+
cve.Cvss2Vector = euvd.BaseScoreVector
84+
switch {
85+
case euvd.BaseScore >= 7.0:
86+
cve.Cvss2Severity = "HIGH"
87+
case euvd.BaseScore >= 4.0:
88+
cve.Cvss2Severity = "MEDIUM"
89+
default:
90+
cve.Cvss2Severity = "LOW"
91+
}
92+
case "3.0", "3.1":
93+
cve.Cvss3Score = euvd.BaseScore
94+
cve.Cvss3Vector = euvd.BaseScoreVector
95+
switch {
96+
case euvd.BaseScore >= 9.0:
97+
cve.Cvss3Severity = "CRITICAL"
98+
case euvd.BaseScore >= 7.0:
99+
cve.Cvss3Severity = "HIGH"
100+
case euvd.BaseScore >= 4.0:
101+
cve.Cvss3Severity = "MEDIUM"
102+
case euvd.BaseScore >= 0.1:
103+
cve.Cvss3Severity = "LOW"
104+
default:
105+
cve.Cvss3Severity = "NONE"
106+
}
107+
case "4.0":
108+
cve.Cvss40Score = euvd.BaseScore
109+
cve.Cvss40Vector = euvd.BaseScoreVector
110+
switch {
111+
case euvd.BaseScore >= 9.0:
112+
cve.Cvss40Severity = "CRITICAL"
113+
case euvd.BaseScore >= 7.0:
114+
cve.Cvss40Severity = "HIGH"
115+
case euvd.BaseScore >= 4.0:
116+
cve.Cvss40Severity = "MEDIUM"
117+
case euvd.BaseScore >= 0.1:
118+
cve.Cvss40Severity = "LOW"
119+
default:
120+
cve.Cvss40Severity = "NONE"
121+
}
122+
default:
123+
}
124+
125+
cves = append(cves, cve)
126+
}
127+
return cves
128+
}
129+
57130
// ConvertNvdToModel convert NVD to CveContent
58131
func ConvertNvdToModel(cveID string, nvds []cvedict.Nvd) ([]CveContent, []Exploit, []Mitigation) {
59132
cves := []CveContent{}

models/utils_test.go

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,185 @@ import (
1313
cvedict "github.com/vulsio/go-cve-dictionary/models"
1414
)
1515

16+
func TestConvertEuvdToModel(t *testing.T) {
17+
type args struct {
18+
cveID string
19+
euvds []cvedict.Euvd
20+
}
21+
tests := []struct {
22+
name string
23+
args args
24+
want []models.CveContent
25+
}{
26+
{
27+
name: "CVE-2025-49575",
28+
args: args{
29+
cveID: "CVE-2025-49575",
30+
euvds: []cvedict.Euvd{
31+
{
32+
EuvdID: "EUVD-2025-18144",
33+
EnisaUUID: "e15c6dcd-bca6-37ab-b0e0-e1cd92a91c98",
34+
Description: "Citizen skin vulnerable to stored XSS through multiple system messages",
35+
DatePublished: time.Date(2025, time.June, 11, 19, 59, 54, 0, time.UTC),
36+
DateUpdated: time.Date(2025, time.June, 13, 03, 43, 58, 0, time.UTC),
37+
References: []cvedict.EuvdReference{
38+
{
39+
Reference: cvedict.Reference{
40+
Link: "https://github.com/StarCitizenTools/mediawiki-skins-Citizen/security/advisories/GHSA-4c2h-67qq-vm87",
41+
Name: "https://github.com/StarCitizenTools/mediawiki-skins-Citizen/security/advisories/GHSA-4c2h-67qq-vm87",
42+
},
43+
},
44+
{
45+
Reference: cvedict.Reference{
46+
Link: "https://nvd.nist.gov/vuln/detail/CVE-2025-49575",
47+
Name: "https://nvd.nist.gov/vuln/detail/CVE-2025-49575",
48+
},
49+
},
50+
},
51+
Aliases: []cvedict.EuvdAlias{
52+
{
53+
Alias: "GHSA-4c2h-67qq-vm87",
54+
},
55+
{
56+
Alias: "CVE-2025-49575",
57+
},
58+
},
59+
},
60+
{
61+
EuvdID: "EUVD-2025-18208",
62+
EnisaUUID: "c8b99a1b-5107-3825-a99f-30d856d6c47e",
63+
Description: "Citizen skin vulnerable to stored XSS through multiple system messages",
64+
DatePublished: time.Date(2025, time.June, 11, 19, 59, 54, 0, time.UTC),
65+
DateUpdated: time.Date(2025, time.June, 13, 03, 43, 58, 0, time.UTC),
66+
BaseScore: 6.5,
67+
BaseScoreVersion: "3.1",
68+
BaseScoreVector: "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N",
69+
References: []cvedict.EuvdReference{
70+
{
71+
Reference: cvedict.Reference{
72+
Link: "https://github.com/StarCitizenTools/mediawiki-skins-Citizen/security/advisories/GHSA-4c2h-67qq-vm87",
73+
Name: "https://github.com/StarCitizenTools/mediawiki-skins-Citizen/security/advisories/GHSA-4c2h-67qq-vm87",
74+
},
75+
},
76+
{
77+
Reference: cvedict.Reference{
78+
Link: "https://nvd.nist.gov/vuln/detail/CVE-2025-49575",
79+
Name: "https://nvd.nist.gov/vuln/detail/CVE-2025-49575",
80+
},
81+
},
82+
},
83+
Aliases: []cvedict.EuvdAlias{
84+
{
85+
Alias: "CVE-2025-49575",
86+
},
87+
},
88+
Assigner: "GitHub_M",
89+
EPSS: 0.02,
90+
},
91+
},
92+
},
93+
want: []models.CveContent{
94+
{
95+
Type: models.Euvd,
96+
CveID: "CVE-2025-49575",
97+
Title: "EUVD-2025-18144",
98+
Summary: "Citizen skin vulnerable to stored XSS through multiple system messages",
99+
SourceLink: "https://euvd.enisa.europa.eu/vulnerability/EUVD-2025-18144",
100+
References: []models.Reference{
101+
{Link: "https://github.com/StarCitizenTools/mediawiki-skins-Citizen/security/advisories/GHSA-4c2h-67qq-vm87"},
102+
{Link: "https://nvd.nist.gov/vuln/detail/CVE-2025-49575"},
103+
},
104+
Published: time.Date(2025, time.June, 11, 19, 59, 54, 0, time.UTC),
105+
LastModified: time.Date(2025, time.June, 13, 03, 43, 58, 0, time.UTC),
106+
},
107+
{
108+
Type: models.Euvd,
109+
CveID: "CVE-2025-49575",
110+
Title: "EUVD-2025-18208",
111+
Summary: "Citizen skin vulnerable to stored XSS through multiple system messages",
112+
Cvss3Score: 6.5,
113+
Cvss3Vector: "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N",
114+
Cvss3Severity: "MEDIUM",
115+
SourceLink: "https://euvd.enisa.europa.eu/vulnerability/EUVD-2025-18208",
116+
References: []models.Reference{
117+
{Link: "https://github.com/StarCitizenTools/mediawiki-skins-Citizen/security/advisories/GHSA-4c2h-67qq-vm87"},
118+
{Link: "https://nvd.nist.gov/vuln/detail/CVE-2025-49575"},
119+
},
120+
Published: time.Date(2025, time.June, 11, 19, 59, 54, 0, time.UTC),
121+
LastModified: time.Date(2025, time.June, 13, 03, 43, 58, 0, time.UTC),
122+
},
123+
},
124+
},
125+
{
126+
name: "CVE-2025-34028",
127+
args: args{
128+
cveID: "CVE-2025-34028",
129+
euvds: []cvedict.Euvd{
130+
{
131+
EuvdID: "EUVD-2025-12275",
132+
EnisaUUID: "631cd45a-4015-314b-b4b4-099d07280668",
133+
Description: "The Commvault Command Center Innovation Release allows an unauthenticated actor to upload ZIP files that represent install packages that, when expanded by the target server, are vulnerable to path traversal vulnerability that can result in Remote Code Execution via malicious JSP.\n\n\n\n\n\nThis issue affects Command Center Innovation Release: 11.38.0 to 11.38.20. The vulnerability is fixed in 11.38.20 with SP38-CU20-433 and SP38-CU20-436 and also fixed in 11.38.25 with SP38-CU25-434 and SP38-CU25-438.",
134+
DatePublished: time.Date(2025, time.April, 22, 16, 32, 23, 0, time.UTC),
135+
DateUpdated: time.Date(2025, time.November, 29, 02, 06, 36, 0, time.UTC),
136+
BaseScore: 9.3,
137+
BaseScoreVersion: "4.0",
138+
BaseScoreVector: "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:H/VA:H/SC:L/SI:H/SA:H",
139+
References: []cvedict.EuvdReference{
140+
{
141+
Reference: cvedict.Reference{
142+
Link: "https://nvd.nist.gov/vuln/detail/CVE-2025-34028",
143+
Name: "https://nvd.nist.gov/vuln/detail/CVE-2025-34028",
144+
},
145+
},
146+
{
147+
Reference: cvedict.Reference{
148+
Link: "https://documentation.commvault.com/securityadvisories/CV_2025_04_1.html",
149+
Name: "https://documentation.commvault.com/securityadvisories/CV_2025_04_1.html",
150+
},
151+
},
152+
},
153+
Aliases: []cvedict.EuvdAlias{
154+
{
155+
Alias: "CVE-2025-34028",
156+
},
157+
{
158+
Alias: "GHSA-6q9c-pjw5-5rjm",
159+
},
160+
},
161+
Assigner: "VulnCheck",
162+
EPSS: 45.93,
163+
ExploitedSince: func() *time.Time { t := time.Date(2025, time.May, 02, 12, 00, 00, 0, time.UTC); return &t }(),
164+
},
165+
},
166+
},
167+
want: []models.CveContent{
168+
{
169+
Type: models.Euvd,
170+
CveID: "CVE-2025-34028",
171+
Title: "EUVD-2025-12275",
172+
Summary: "The Commvault Command Center Innovation Release allows an unauthenticated actor to upload ZIP files that represent install packages that, when expanded by the target server, are vulnerable to path traversal vulnerability that can result in Remote Code Execution via malicious JSP.\n\n\n\n\n\nThis issue affects Command Center Innovation Release: 11.38.0 to 11.38.20. The vulnerability is fixed in 11.38.20 with SP38-CU20-433 and SP38-CU20-436 and also fixed in 11.38.25 with SP38-CU25-434 and SP38-CU25-438.",
173+
Cvss40Score: 9.3,
174+
Cvss40Vector: "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:H/VA:H/SC:L/SI:H/SA:H",
175+
Cvss40Severity: "CRITICAL",
176+
SourceLink: "https://euvd.enisa.europa.eu/vulnerability/EUVD-2025-12275",
177+
References: []models.Reference{
178+
{Link: "https://nvd.nist.gov/vuln/detail/CVE-2025-34028"},
179+
{Link: "https://documentation.commvault.com/securityadvisories/CV_2025_04_1.html"},
180+
},
181+
Published: time.Date(2025, time.April, 22, 16, 32, 23, 0, time.UTC),
182+
LastModified: time.Date(2025, time.November, 29, 02, 06, 36, 0, time.UTC),
183+
},
184+
},
185+
},
186+
}
187+
for _, tt := range tests {
188+
t.Run(tt.name, func(t *testing.T) {
189+
if got := models.ConvertEuvdToModel(tt.args.cveID, tt.args.euvds); !reflect.DeepEqual(got, tt.want) {
190+
t.Errorf("ConvertEuvdToModel() = %v, want %v", got, tt.want)
191+
}
192+
})
193+
}
194+
}
16195
func TestConvertVulncheckToModel(t *testing.T) {
17196
type args struct {
18197
cveID string

0 commit comments

Comments
 (0)