From c1a3a44dc43d9cbfe074cb5d8fd09e36112f67a0 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Sat, 19 Feb 2022 22:54:09 -0500 Subject: dbstore: add CveSearch() and test (but not test data) --- dbstore/dbstore.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- dbstore/dbstore_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/dbstore/dbstore.go b/dbstore/dbstore.go index 98f3b61..d1e44ba 100644 --- a/dbstore/dbstore.go +++ b/dbstore/dbstore.go @@ -4,6 +4,7 @@ package dbstore import ( "context" db_sql "database/sql" + "encoding/json" "fmt" _ "github.com/mattn/go-sqlite3" "github.com/pablotron/cvez/cpedict" @@ -157,6 +158,23 @@ func (me DbStore) Query( return nil } +// Execute query and invoke callback with each row of result. +func (me DbStore) QueryRow( + ctx context.Context, + queryId string, + args []interface{}, + fn func (*db_sql.Row) error, +) error { + // get query + sql, err := getQuery(queryId) + if err != nil { + return err + } + + // exec query, invoke callback, return result + return fn(me.db.QueryRowContext(ctx, sql, args...)) +} + // import CPE dictionary func (me DbStore) AddCpeDictionary(ctx context.Context, dict cpedict.Dictionary) error { // lazy-init db @@ -685,7 +703,7 @@ var addCveFeedQueryIds = []string { "feed/insert-item-cvss-v3", } -// Add CVE feed. +// Import CVE feed. func (me DbStore) AddCveFeed(ctx context.Context, feed nvd_feed.Feed) (int64, error) { // feed ID var feedId int64 @@ -709,3 +727,32 @@ func (me DbStore) AddCveFeed(ctx context.Context, feed nvd_feed.Feed) (int64, er // return result return feedId, err } + +// search CVEs +func (me DbStore) CveSearch( + ctx context.Context, + s string, +) ([]CveSearchRow, error) { + var r []CveSearchRow + + // lazy-init db + if err := me.Init(ctx); err != nil { + return r, err + } + + // get/exec search query + err := me.QueryRow(ctx, "feed/search", []interface{} { + db_sql.Named("q", s), + }, func(row *db_sql.Row) error { + var s string + if err := row.Scan(&s); err != nil { + return err + } + + return json.Unmarshal([]byte(s), &r) + }) + + // return results + return r, err +} + diff --git a/dbstore/dbstore_test.go b/dbstore/dbstore_test.go index ea5d284..2dcadfa 100644 --- a/dbstore/dbstore_test.go +++ b/dbstore/dbstore_test.go @@ -1005,3 +1005,31 @@ func TestAddCveFeed(t *testing.T) { }) } } + +func TestCveSearch(t *testing.T) { + ctx := context.Background() + + tests := []string { + "cisco anyconnect ipc dll mobility secure", + } +// [{"nvd_cve_id":"CVE-2021-1366","rank":-36.4874758136269,"description":"A vulnerability in the interprocess communication (IPC) channel of Cisco AnyConnect Secure Mobility Client for Windows could allow an authenticated, local attacker to perform a DLL hijacking attack on an affected device if the VPN Posture (HostScan) Module is installed on the AnyConnect client. This vulnerability is due to insufficient validation of resources that are loaded by the application at run time. An attacker could exploit this vulnerability by sending a crafted IPC message to the AnyConnect process. A successful exploit could allow the attacker to execute arbitrary code on the affected machine with SYSTEM privileges. To exploit this vulnerability, the attacker needs valid credentials on the Windows system."},{"nvd_cve_id":"CVE-2021-1567","rank":-34.6220092956805,"description":"A vulnerability in the DLL loading mechanism of Cisco AnyConnect Secure Mobility Client for Windows could allow an authenticated, local attacker to perform a DLL hijacking attack on an affected device if the VPN Posture (HostScan) Module is installed on the AnyConnect client. This vulnerability is due to a race condition in the signature verification process for DLL files that are loaded on an affected device. An attacker could exploit this vulnerability by sending a series of crafted interprocess communication (IPC) messages to the AnyConnect process. A successful exploit could allow the attacker to execute arbitrary code on the affected device with SYSTEM privileges. To exploit this vulnerability, the attacker must have valid credentials on the Windows system."}] + + // open test db + db, err := Open("testdata/cvesearch-test.db") + if err != nil { + t.Error(err) + return + } + + // run tests + for _, test := range(tests) { + t.Run(test, func(t *testing.T) { + rows, err := db.CveSearch(ctx, test) + if err != nil { + t.Error(err) + } else { + t.Errorf("success: got %v", rows) + } + }) + } +} -- cgit v1.2.3