Latest Dynatrace
Container image scanning is usually performed in artifact repositories, such as AWS Elastic Container Registry (ECR), GCP Artifact Registry, and Microsoft Azure Container Registry. After the images are deployed in production, continuous reassessing of the container images is essential to ensure they're not affected by emerging critical vulnerabilities.
The number of vulnerability findings grows with the number of stored container images, and the development team might become overwhelmed by the number of critical findings. Some of the container images will never be deployed to your production environment. They might be part of your test environments or become obsolete and lay in the repository as a legacy.
In this context, Dynatrace helps you
Reduce alert fatigue
Focus remediation efforts on the critical vulnerability findings that significantly impact your production applications
Site reliability engineers (SREs) and application owners who want to maintain the security hygiene and health of their applications.
The development team stores container images in Amazon ECR. Later on, those images are deployed into staging and production environments running on Kubernetes.
You monitor the health of your applications with Dynatrace OneAgent in Kubernetes.
Several new critical vulnerabilities have been discovered recently by Amazon ECR in the container images.
Avoid critical vulnerability exposure in production applications on containers with vulnerable container images.
Our solution allows you to
Use our sample dashboard to view the summarized and unified list of recent vulnerability findings ingested from Amazon ECR.
Download our sample dashboard from GitHub.
Open Dashboards, select Upload, then select the downloaded file.
Example dashboard:
Filter for RuntimeStatus
to display contextualized findings affecting your runtime containers.
Filter for ProductStage
to display contextualized findings affecting your production services and applications.
You can adjust our automation workflow samples to enrich and filter external container image vulnerability findings for runtime context. For details, see Automate and orchestrate security findings.
Example query to get new critical container image vulnerabilities with a list of the affected container images and running containers:
// The query has a rolling window of 7 days and the last 24hrs.// Vulnerability finding events which have already been reported// before the current 24hr window will not be reported again.fetch events, from: now() - 7d| filter dt.system.bucket == "default_security_custom_events"AND event.kind == "SECURITY_EVENT"AND object.type == "CONTAINER_IMAGE"AND event.type == "VULNERABILITY_FINDING"AND dt.security.risk.level == "CRITICAL"// now enrich the runtime context| join [fetch dt.entity.container_group_instance, from:now()-3h| fieldsAdd entity.name, containerImageDigest, containerImageName, workloadName, containerStatus, processes=contains[dt.entity.process_group_instance]| expand dt.entity.process=processes| fieldsRemove processes| join [fetch dt.entity.process_group_instance, from:now()-3h], on:{left[dt.entity.process]==right[id]}, kind:leftOuter, fields:{releasesProduct, releasesStage}], on:{left[container_image.digest]==right[containerImageDigest]}, kind:leftOuter,fields:{container_instance.id=id, container_instance.name=entity.name, container_image.name=containerImageName,releasesProduct, releasesStage, containerStatus}// summarize and filter| dedup {object.id, vulnerability.id, component.name, component.version,container_image.registry, container_image.repository}, sort: {timestamp desc}| parse containerStatus, """LD* "state=" LD:containerStatus ("}" | ",")"""| fieldsAdd containerStatus=if(isNull(containerStatus),"not running",else:containerStatus)| fieldsAdd releasesStage=if(isNull(releasesStage), "None", else:releasesStage)| filter containerStatus=="running" AND releasesStage=="production"// Aggregate vulnerability findings per vulnerability, repository,// component and component version.| summarize {affected_images_count = count(),vulnerability_finding_events = collectArray(record(object.id = object.id,event.provider = event.provider,container_image.registry = container_image.registry,container_image.repository = container_image.repository,component.version = component.version,component.name = component.name,dt.security.risk.level = dt.security.risk.level,ingest_time = timestamp))}, by:{ vulnerability.id, vulnerability.title, event.provider, container_image.registry, container_image.repository, component.name, component.version }// Filter out, if this vulnerability for the repository and the component// and version was already reported before the last 24 hours.// For example, if the same vulnerability was reported multiple times// during the last 7 days, don't report it again.| filterOut iAny(vulnerability_finding_events[][ingest_time] < now() - 24h)// Expand and deduplicate for repetitive findings if they// were reported more than once in the last 24 hours.| expand vulnerability_finding_events| dedup { vulnerability.id, vulnerability.title, vulnerability_finding_events[object.id], vulnerability_finding_events[component.name], vulnerability_finding_events[component.version] }// Aggregate again to count the unique affected images within each repository.| summarize {affected_images_count = count(),vulnerability_finding_events = collectArray(vulnerability_finding_events)}, by:{ vulnerability.id, vulnerability.title, event.provider, container_image.registry, container_image.repository, component.name, component.version }| sort vulnerability_finding_events[][ingest_time] desc
Example result:
To track the alert reduction process based on the progressive filtering in step 2, you can download and use our Runtime contextualization of container findings for alert reduction dashboard.
Example result: