From 87ab4ae4c0f3f8d9767b499f203aae09b25592ff Mon Sep 17 00:00:00 2001 From: becitsthere Date: Tue, 14 May 2024 10:51:43 -0700 Subject: [PATCH] NVSHAS-8739,8988: Report all occurrences of vul in different files (2) --- go.mod | 2 +- go.sum | 4 +- .../neuvector/neuvector/share/scan/apps.go | 106 +++++++++++++----- vendor/modules.txt | 2 +- 4 files changed, 84 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index a00581ac..5acc5586 100644 --- a/go.mod +++ b/go.mod @@ -46,7 +46,7 @@ require ( github.com/google/uuid v1.3.0 github.com/jedib0t/go-pretty/v6 v6.4.6 github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/neuvector/neuvector v0.0.0-20240514014848-57ed2aca9488 + github.com/neuvector/neuvector v0.0.0-20240514174641-ad80e5f38bcc github.com/opencontainers/go-digest v1.0.0 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.8.2 // indirect diff --git a/go.sum b/go.sum index b5c0218d..c7bb7d12 100644 --- a/go.sum +++ b/go.sum @@ -673,8 +673,8 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96d github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/neuvector/k8s v1.2.1-0.20220214174348-d0b3f377461e h1:y7w21QaxlBzeRNW1PEdBfR/rA0S801uCEvubsiq1AJ0= github.com/neuvector/k8s v1.2.1-0.20220214174348-d0b3f377461e/go.mod h1:djxl7Js+tfAJJgxKpeN3lnFZT6jRhl1Ikkgd/wMrLQU= -github.com/neuvector/neuvector v0.0.0-20240514014848-57ed2aca9488 h1:kItUSS9m5GFWeNSAIj3E87T3xLu3Y757YF7rjC3VgOk= -github.com/neuvector/neuvector v0.0.0-20240514014848-57ed2aca9488/go.mod h1:jSdathPtRTSMDrQz5m/WMYJA/zfVR8tGVfuthRCZo6A= +github.com/neuvector/neuvector v0.0.0-20240514174641-ad80e5f38bcc h1:paysScCqUEU7OfcNOkhgkOKgl5+e1ozmeg1I1tuz6MA= +github.com/neuvector/neuvector v0.0.0-20240514174641-ad80e5f38bcc/go.mod h1:jSdathPtRTSMDrQz5m/WMYJA/zfVR8tGVfuthRCZo6A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= diff --git a/vendor/github.com/neuvector/neuvector/share/scan/apps.go b/vendor/github.com/neuvector/neuvector/share/scan/apps.go index 384de210..cd7dddb4 100644 --- a/vendor/github.com/neuvector/neuvector/share/scan/apps.go +++ b/vendor/github.com/neuvector/neuvector/share/scan/apps.go @@ -15,8 +15,6 @@ import ( "strings" log "github.com/sirupsen/logrus" - - "github.com/neuvector/neuvector/share/utils" ) const ( @@ -26,7 +24,7 @@ const ( nodeModules2 = "/usr/local/lib/node_modules" nodeModules = "node_modules" nodePackage = "package.json" - nodeJs = "node.js" + nodeJs = "npm" wpname = "Wordpress" WPVerFileSuffix = "wp-includes/version.php" @@ -55,6 +53,13 @@ const ( dotnetDepsMaxSize = 10 * 1024 * 1024 golang = "golang" + + // R language + rlang = "r" + rDefaultPath = "usr/lib/R/library/" + rDefaultPath2 = "usr/local/lib/R/library/" + rRepositoryPath = "usr/local/lib/R/site-library/" + rDescFileName = "DESCRIPTION" ) var verRegexp = regexp.MustCompile(`<([a-zA-Z0-9\.]+)>([0-9\.]+)`) @@ -112,18 +117,17 @@ type dotnetPackage struct { } type ScanApps struct { - dedup utils.Set // Used by some apps to remove duplicated modules pkgs map[string][]AppPackage // AppPackage set replace bool } func NewScanApps(v2 bool) *ScanApps { - return &ScanApps{pkgs: make(map[string][]AppPackage), dedup: utils.NewSet(), replace: v2} + return &ScanApps{pkgs: make(map[string][]AppPackage), replace: v2} } func IsAppsPkgFile(filename, fullpath string) bool { if isNodejs(filename) || IsJava(filename) || isPython(filename) || - isRuby(filename) || isDotNet(filename) || isWordpress(filename) || isPhpComposer(filename) { + isRuby(filename) || isDotNet(filename) || isWordpress(filename) || isPhpComposer(filename) || IsRlangPackage(filename) { return true } // Keep golang check at last as it requires reading file data @@ -185,6 +189,8 @@ func (s *ScanApps) ExtractAppPkg(filename, fullpath string) { s.parseWordpressPackage(filename, fullpath) } else if isPhpComposer(filename) { s.parsePhpComposerJson(filename, fullpath) + } else if IsRlangPackage(filename) { + s.parseRLangPackage(filename, fullpath) } else { s.parseGolangPackage(filename, fullpath) } @@ -425,7 +431,7 @@ func parseJarManifestFile(path string, rc io.Reader) (*AppPackage, error) { return &pkg, nil } -func (s *ScanApps) parseJarPackage(r zip.Reader, tfile, filename, fullpath string, depth int) { +func (s *ScanApps) parseJarPackage(r zip.Reader, origJar, filename, fullpath string, depth int) { tempDir, err := ioutil.TempDir("", "") if err == nil { defer os.RemoveAll(tempDir) @@ -436,7 +442,7 @@ func (s *ScanApps) parseJarPackage(r zip.Reader, tfile, filename, fullpath strin // the real filepath path := filename if depth > 0 { - path = tfile + ":" + filename + path = origJar + ":" + filename } pkgs := make(map[string][]AppPackage) @@ -453,7 +459,7 @@ func (s *ScanApps) parseJarPackage(r zip.Reader, tfile, filename, fullpath strin if _, err := io.Copy(dstFile, jarFile); err == nil { dstFile.Close() if jarReader, err := zip.OpenReader(dstPath); err == nil { - s.parseJarPackage(jarReader.Reader, tfile, f.Name, dstPath, depth+1) + s.parseJarPackage(jarReader.Reader, origJar, f.Name, dstPath, depth+1) jarReader.Close() } } else { @@ -509,7 +515,12 @@ func (s *ScanApps) parseJarPackage(r zip.Reader, tfile, filename, fullpath strin ModuleName: fmt.Sprintf("%s:%s", groupId, artifactId), Version: version, } - pkgs[path] = []AppPackage{pkg} + if _, ok := pkgs[path]; !ok { + pkgs[path] = []AppPackage{pkg} + } else { + pkgs[path] = append(pkgs[path], pkg) + } + continue //higher priority } else if strings.HasSuffix(f.Name, javaManifest) { rc, err := f.Open() @@ -519,7 +530,11 @@ func (s *ScanApps) parseJarPackage(r zip.Reader, tfile, filename, fullpath strin } if pkg, err := parseJarManifestFile(path, rc); err == nil { - pkgs[path] = []AppPackage{*pkg} + if _, ok := pkgs[path]; !ok { + pkgs[path] = []AppPackage{*pkg} + } else { + pkgs[path] = append(pkgs[path], *pkg) + } } rc.Close() @@ -551,6 +566,13 @@ func isPhpComposer(filename string) bool { return strings.HasSuffix(filename, ComposerFile) } +func IsRlangPackage(filename string) bool { + if filepath.Base(filename) != rDescFileName { + return false + } + return strings.HasPrefix(filename, rDefaultPath) || strings.HasPrefix(filename, rRepositoryPath) || strings.HasPrefix(filename, rDefaultPath2) +} + func (s *ScanApps) parsePhpComposerJson(filename string, filepath string) { data := ComposerLock{} //extract json data @@ -578,7 +600,7 @@ func (s *ScanApps) parsePhpComposerJson(filename string, filepath string) { if _, ok := s.pkgs[filename]; !ok { s.pkgs[filename] = []AppPackage{appPackage} } else { - s.pkgs[filename] = append(s.pkgs[appPackage.ModuleName], appPackage) + s.pkgs[filename] = append(s.pkgs[filename], appPackage) } } } @@ -730,13 +752,7 @@ func (s *ScanApps) parseDotNetPackage(filename, fullpath string) { Version: v, FileName: filename, } - - // There can be several files that list the same dependency, such as .NET Core, so to dedup them - key := fmt.Sprintf("%s-%s-%s", pkg.AppName, pkg.ModuleName, pkg.Version) - if !s.dedup.Contains(key) { - s.dedup.Add(key) - pkgs = append(pkgs, pkg) - } + pkgs = append(pkgs, pkg) } } } @@ -748,16 +764,54 @@ func (s *ScanApps) parseDotNetPackage(filename, fullpath string) { Version: coreVersion, FileName: filename, } - - // There can be several files that list the same dependency, such as .NET Core, so to dedup them - key := fmt.Sprintf("%s-%s-%s", pkg.AppName, pkg.ModuleName, pkg.Version) - if !s.dedup.Contains(key) { - s.dedup.Add(key) - pkgs = append(pkgs, pkg) - } + pkgs = append(pkgs, pkg) } if len(pkgs) > 0 { s.pkgs[filename] = pkgs } } + +func (s *ScanApps) parseRLangPackage(filename, fullpath string) { + if _, err := os.Stat(fullpath); err != nil { + log.WithFields(log.Fields{"err": err, "fullpath": fullpath, "filename": filename}).Error("Failed to stat file") + return + } + + var name, version, repository string + + inputFile, err := os.Open(fullpath) + if err != nil { + log.WithFields(log.Fields{"err": err, "fullpath": fullpath, "filename": filename}).Debug("Open file fail") + return + } + defer inputFile.Close() + + scanner := bufio.NewScanner(inputFile) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if strings.HasPrefix(line, "Package: ") { + name = strings.TrimSpace(strings.TrimPrefix(line, "Package: ")) + } else if strings.HasPrefix(line, "Version: ") { + version = strings.TrimSpace(strings.TrimPrefix(line, "Version: ")) + } else if strings.HasPrefix(line, "Repository:") { + repository = strings.TrimSpace(strings.TrimPrefix(line, "Repository: ")) + } + } + + if name != "" { + var rname string + if repository == "" { + rname = name + } else { + rname = fmt.Sprintf("%s-%s", repository, name) + } + pkg := AppPackage { + AppName: rlang, + ModuleName: strings.ToLower(rname), + Version: version, + FileName: strings.TrimSuffix(filename, "/"+ rDescFileName), + } + s.pkgs[filename] = []AppPackage{pkg} + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ee5b7c42..165ae247 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -173,7 +173,7 @@ github.com/mitchellh/mapstructure github.com/neuvector/k8s/apis/meta/v1 github.com/neuvector/k8s/runtime github.com/neuvector/k8s/runtime/schema -# github.com/neuvector/neuvector v0.0.0-20240514014848-57ed2aca9488 +# github.com/neuvector/neuvector v0.0.0-20240514174641-ad80e5f38bcc ## explicit github.com/neuvector/neuvector/controller/api github.com/neuvector/neuvector/share