Exemplo n.º 1
0
        private async Task <ContainerImageScanResult> CalculateCounters(ImageScanResultEntity scan)
        {
            var cves = await this.db.Set <ImageScanToCveEntity>()
                       .Include("CVE")
                       .AsNoTracking()
                       .Where(i => i.ScanId == scan.Id)
                       .Select(i => new { i.CVE.Id, i.CVE.Severity })
                       .ToArrayAsync();

            var counters = cves
                           .GroupBy(i => i.Severity)
                           .Select(i => new VulnerabilityCounters()
            {
                Count = i.Count(), Severity = i.Key.ToString()
            })
                           .ToArray();

            return(new ContainerImageScanResult
            {
                Image = scan.ImageTag,
                ScanResult = ScanResult.Succeeded,
                Counters = counters,
                Date = scan.Date,
            });
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates Image Scan entity from internal model.
        /// </summary>
        /// <param name="scan">Internal Image Scan model.</param>
        /// <returns>Database compatible entity.</returns>
        public static ImageScanResultEntity ToEntity(this ImageScanResultWithCVEs scan)
        {
            var entity = new ImageScanResultEntity
            {
                ExternalId  = scan.Id,
                ImageTag    = scan.ImageTag,
                Date        = scan.Date,
                Status      = scan.Status.ToEntity(),
                Description = scan.Description,
                FoundCVEs   = scan.FoundCVEs?.Select(i => i.ToEntity()).ToList(),
            };

            return(entity);
        }
Exemplo n.º 3
0
        private async Task <ContainerImageScanResult> ParseCveDetails(ImageScanResultEntity scan)
        {
            var cves = await this.db.Set <ImageScanToCveEntity>()
                       .Include("CVE")
                       .AsNoTracking()
                       .Where(i => i.ScanId == scan.Id)
                       .Select(i => new { i.Target, i.UsedPackage, i.UsedPackageVersion, i.CVE.CveId, i.CVE.Severity, i.CVE.PackageName, i.CVE.Description, i.CVE.Title, i.CVE.References, i.CVE.Remediation })
                       .ToArrayAsync();

            var targets = new List <ImageScanTarget>();

            foreach (var target in cves.GroupBy(i => i.Target))
            {
                var vulnerabilities = new List <VulnerabilityDescription>();
                foreach (var groupedByCve in target.GroupBy(i => i.CveId))
                {
                    var cve = groupedByCve.First();
                    vulnerabilities.Add(new VulnerabilityDescription
                    {
                        VulnerabilityID     = cve.CveId,
                        PkgName             = cve.PackageName,
                        Title               = cve.Title,
                        Severity            = cve.Severity.ToString(),
                        Description         = cve.Description,
                        DependenciesWithCVE = groupedByCve.Select(i => i.UsedPackage).ToArray(),
                        InstalledVersion    = cve.UsedPackageVersion,
                        Remediation         = cve.Remediation,
                        References          = string.IsNullOrEmpty(cve.References)
                            ? new string[0]
                            : cve.References.Split(TrivyAuditProcessor.LineSeparator).Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(),
                    });
                }

                targets.Add(new ImageScanTarget
                {
                    Target          = target.Key,
                    Vulnerabilities = vulnerabilities.ToArray(),
                });
            }

            return(new ContainerImageScanResult
            {
                Image = scan.ImageTag,
                ScanResult = ScanResult.Succeeded,
                Counters = new VulnerabilityCounters[0],
                Targets = targets.ToArray(),
                Date = scan.Date,
            });
        }
        public void GetShortResultImageScanCalculatesCorrectCounters()
        {
            // Arrange
            // create 1 critical, 2 high, 3 medium, 4 low, 5 unknown severity issues
            var entity = new ImageScanResultEntity
            {
                FoundCVEs = new List <ImageScanToCveEntity>
                {
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Critical
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.High
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.High
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Medium
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Medium
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Medium
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Low
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Low
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Low
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Low
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Unknown
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Unknown
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Unknown
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Unknown
                        }
                    },
                    new ImageScanToCveEntity {
                        CVE = new CveEntity {
                            Severity = CveSeverity.Unknown
                        }
                    },
                },
            };

            // Act
            var scanResult = entity.GetShortResult();

            // Assert
            scanResult.Counters.Should().HaveCount(5);
            scanResult.Counters.First(i => i.Severity == webapp.Database.Models.CveSeverity.Critical).Count.Should().Be(1);
            scanResult.Counters.First(i => i.Severity == webapp.Database.Models.CveSeverity.High).Count.Should().Be(2);
            scanResult.Counters.First(i => i.Severity == webapp.Database.Models.CveSeverity.Medium).Count.Should().Be(3);
            scanResult.Counters.First(i => i.Severity == webapp.Database.Models.CveSeverity.Low).Count.Should().Be(4);
            scanResult.Counters.First(i => i.Severity == webapp.Database.Models.CveSeverity.Unknown).Count.Should().Be(5);
        }
        public async Task SaveImageScanResultCouldUpdateExistingEntity()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();

            var queuedScan = new ImageScanResultEntity
            {
                Date        = DateTime.UtcNow.AddMinutes(-10),
                ExternalId  = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString(),
                ImageTag    = Guid.NewGuid().ToString(),
                Status      = joseki.db.entities.ImageScanStatus.Queued,
            };

            context.Set <ImageScanResultEntity>().Add(queuedScan);
            await context.SaveChangesAsync();

            var scan = new ImageScanResultWithCVEs
            {
                Date        = DateTime.UtcNow,
                Id          = queuedScan.ExternalId,
                Description = Guid.NewGuid().ToString(),
                ImageTag    = queuedScan.ImageTag,
                Status      = ImageScanStatus.Succeeded,
                FoundCVEs   = new List <ImageScanToCve>
                {
                    new ImageScanToCve {
                        InternalCveId = 1, Target = Guid.NewGuid().ToString(), UsedPackage = Guid.NewGuid().ToString(), UsedPackageVersion = Guid.NewGuid().ToString()
                    },
                    new ImageScanToCve {
                        InternalCveId = 2, Target = Guid.NewGuid().ToString(), UsedPackage = Guid.NewGuid().ToString(), UsedPackageVersion = Guid.NewGuid().ToString()
                    },
                    new ImageScanToCve {
                        InternalCveId = 3, Target = Guid.NewGuid().ToString(), UsedPackage = Guid.NewGuid().ToString(), UsedPackageVersion = Guid.NewGuid().ToString()
                    },
                },
            };

            var parser = new ConfigurationParser("config.sample.yaml");
            var db     = new MssqlJosekiDatabase(context, parser);

            // Act & Assert
            context.ImageScanResult.Should().HaveCount(1);
            context.ImageScanResultToCve.Should().HaveCount(0);

            await db.SaveImageScanResult(scan);

            context.ImageScanResult.Should().HaveCount(1);
            context.ImageScanResultToCve.Should().HaveCount(scan.FoundCVEs.Count);

            // Only Date, Description, Status, and CVEs should be updated
            var actual = await context.ImageScanResult.FirstAsync();

            actual.Date.Should().Be(scan.Date);
            actual.Description.Should().Be(scan.Description);
            actual.Status.Should().Be(joseki.db.entities.ImageScanStatus.Succeeded);

            foreach (var actualCve in await context.ImageScanResultToCve.ToArrayAsync())
            {
                var expectedCve = scan.FoundCVEs.First(i => i.InternalCveId == actualCve.CveId);
                actualCve.Target.Should().Be(expectedCve.Target);
                actualCve.UsedPackage.Should().Be(expectedCve.UsedPackage);
                actualCve.UsedPackageVersion.Should().Be(expectedCve.UsedPackageVersion);
            }
        }