Skip to content

Commit f7a0738

Browse files
committed
Fix false positives in Java dependencies
See neuvector/neuvector#2205 for more details.
1 parent d89887f commit f7a0738

File tree

3 files changed

+367
-9
lines changed

3 files changed

+367
-9
lines changed

common/db.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,6 @@ func LoadAppVulsTb(path string) (map[string][]AppModuleVul, error) {
499499
}
500500

501501
for _, mn := range mns {
502-
colon := strings.LastIndex(mn, ":")
503502
m := strings.ReplaceAll(mn, ":", ".")
504503
vf := vul[mn]
505504

@@ -508,14 +507,6 @@ func LoadAppVulsTb(path string) (map[string][]AppModuleVul, error) {
508507
} else {
509508
vul[m] = vf
510509
}
511-
if m = mn[colon+1:]; len(m) > 0 {
512-
key := fmt.Sprintf("jar:%s", m)
513-
if _, ok := vul[key]; ok {
514-
vul[key] = uniqueVulDb(append(vul[key], vf...))
515-
} else {
516-
vul[key] = vf
517-
}
518-
}
519510
}
520511
return vul, nil
521512
}

common/db_test.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,50 @@ func prepareMockDbPaths(t *testing.T, encryptKey []byte, timestamp time.Time) (s
162162
return dbPath, expandRoot
163163
}
164164

165+
func writeAppsTb(t *testing.T, dir string, entries ...AppModuleVul) {
166+
t.Helper()
167+
var buf bytes.Buffer
168+
for _, e := range entries {
169+
data, err := json.Marshal(e)
170+
require.NoError(t, err)
171+
buf.Write(data)
172+
buf.WriteByte('\n')
173+
}
174+
require.NoError(t, os.WriteFile(filepath.Join(dir, "apps.tb"), buf.Bytes(), 0644))
175+
}
176+
177+
func loadAppsTb(t *testing.T, entries ...AppModuleVul) map[string][]AppModuleVul {
178+
t.Helper()
179+
dir := t.TempDir()
180+
writeAppsTb(t, dir, entries...)
181+
vul, err := LoadAppVulsTb(dir)
182+
require.NoError(t, err)
183+
return vul
184+
}
185+
186+
func newJarVul(cveName, moduleName, severity, fixedBefore string) AppModuleVul {
187+
return AppModuleVul{
188+
VulName: cveName,
189+
AppName: "jar",
190+
ModuleName: moduleName,
191+
Severity: severity,
192+
AffectedVer: []AppModuleVersion{{OpCode: "lt", Version: fixedBefore}},
193+
}
194+
}
195+
196+
func requireKeyExists(t *testing.T, vul map[string][]AppModuleVul, key string) []AppModuleVul {
197+
t.Helper()
198+
v, ok := vul[key]
199+
require.True(t, ok, "expected key %q to exist", key)
200+
return v
201+
}
202+
203+
func requireKeyAbsent(t *testing.T, vul map[string][]AppModuleVul, key string) {
204+
t.Helper()
205+
_, ok := vul[key]
206+
require.False(t, ok, "key %q must NOT exist", key)
207+
}
208+
165209
func TestLoadCveDB(t *testing.T) {
166210
testCases := []struct {
167211
name string
@@ -284,3 +328,63 @@ func TestLoadCveDB(t *testing.T) {
284328
})
285329
}
286330
}
331+
332+
func TestLoadAppVulsTb_NoJarShortcutKeys(t *testing.T) {
333+
vul := loadAppsTb(t,
334+
newJarVul("CVE-2021-0341", "com.squareup.okhttp3:okhttp", "High", "4.9.3"),
335+
newJarVul("CVE-2022-20621", "org.jenkins-ci.plugins:metrics", "Medium", "4.2.0"),
336+
newJarVul("CVE-2018-1000011", "org.jvnet.hudson.plugins:findbugs:library", "High", "4.72"),
337+
)
338+
339+
// --- Verify original groupId:artifactId keys ARE present ---
340+
okhttp := requireKeyExists(t, vul, "com.squareup.okhttp3:okhttp")
341+
requireKeyExists(t, vul, "org.jenkins-ci.plugins:metrics")
342+
requireKeyExists(t, vul, "org.jvnet.hudson.plugins:findbugs:library")
343+
344+
// --- Verify dot-separated backward-compat keys ARE present ---
345+
okhttpDot := requireKeyExists(t, vul, "com.squareup.okhttp3.okhttp")
346+
requireKeyExists(t, vul, "org.jenkins-ci.plugins.metrics")
347+
348+
// --- Verify jar: shortcut keys are NOT present ---
349+
for _, key := range []string{"jar:okhttp", "jar:metrics", "jar:library", "jar:findbugs:library"} {
350+
requireKeyAbsent(t, vul, key)
351+
}
352+
353+
// --- Verify CVE data integrity for existing keys ---
354+
require.Len(t, okhttp, 1)
355+
require.Equal(t, "CVE-2021-0341", okhttp[0].VulName)
356+
357+
// Dot-separated key should have same data
358+
require.Len(t, okhttpDot, 1)
359+
require.Equal(t, "CVE-2021-0341", okhttpDot[0].VulName)
360+
}
361+
362+
func TestLoadAppVulsTb_NoColonModuleName(t *testing.T) {
363+
vul := loadAppsTb(t, AppModuleVul{
364+
VulName: "CVE-2099-0001",
365+
AppName: "npm",
366+
ModuleName: "lodash",
367+
Severity: "High",
368+
AffectedVer: []AppModuleVersion{{OpCode: "lt", Version: "4.17.21"}},
369+
})
370+
371+
requireKeyExists(t, vul, "lodash")
372+
requireKeyAbsent(t, vul, "jar:lodash")
373+
require.Len(t, vul, 1)
374+
}
375+
376+
func TestLoadAppVulsTb_MultipleVulsSameModule(t *testing.T) {
377+
vul := loadAppsTb(t,
378+
newJarVul("CVE-2021-0341", "com.squareup.okhttp3:okhttp", "High", "4.9.3"),
379+
newJarVul("CVE-2016-2402", "com.squareup.okhttp3:okhttp", "Medium", "3.1.2"),
380+
)
381+
382+
// Both CVEs should be under the same key
383+
require.Len(t, vul["com.squareup.okhttp3:okhttp"], 2)
384+
385+
// Dot-separated should also have both
386+
require.Len(t, vul["com.squareup.okhttp3.okhttp"], 2)
387+
388+
// No jar: key
389+
requireKeyAbsent(t, vul, "jar:okhttp")
390+
}

0 commit comments

Comments
 (0)