--- tags: ECR, Inspector, Guard Duty, Containers, AWS, Blog --- # Native Amazon ECR vulnerability scanning in your container image builds phase ![alt text](https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/main/source/unofficial/AWS-Architecture-Icons_SVG_20200430/SVG%20Light/_Group%20Icons/AWS-Cloud-alt_light-bg.svg "Tech Series" =20x20) Integrating security measures in your rudimentary pipeline build and releases of container images is a critical part of building an application in the [AWS Shared Responsibility Model](https://aws.amazon.com/compliance/shared-responsibility-model/). Build tasks like Dockerfile linting, secret scanning and vulnerability scanning should all be integrated within your AWS CodeBuild as they are important security controls before an image is used in an application. Up until now for vulnerability scanning the choice of many is to use third party solutions like [Anchore](https://anchore.com/opensource/) which is primarily used for checking your image for any Common Vulnerabilities and Exposure (CVE). Amazon Elastic Container Registry (ECR) now supports [Image Scanning](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html) where we can do this via an AWS managed service and no longer have to deploy a [client server API architecture](https://d2908q01vomqb2.cloudfront.net/fe2ef495a1152561572949784c16bf23abb28057/2020/08/12/Screenshot-2020-08-12-at-11.52.42-AM.png) with additional resources within our container builds. To successfully scan our container images using AWS native services we must run the `aws ecr image-scan-compute` aws-cli command during our container image build steps to complete an image scan and wait until the findings can be accessed. The command will poll every 5 seconds until successful state has been reached. The command is a paginated operation and will retrieve the entire data set of results. The identified vulnerability results can be returned in JSON with the following levels of severity - Critical, High, Medium and Low. When the image scan completes we can specify a vulnerability threshold like "*High or Critical*", which upon finding any of the criticalities can fail the build step and subsequent pipeline execution. Unlike third party solutions all the scan findings are natively integrated with Amazon ECR, Amazon Inspector and AWS Security Hub. ## AWS-CLI commands Start a scan: ```bash= aws ecr start-image-scan --repository-name <image-repository-name> --image-id imageTag=<image-tag> ``` Wait for the scan to complete: ```bash= aws ecr wait image-scan-complete --repository-name <image-repository-name> --image-id imageTag=<image-tag> ``` Return the results: ```bash= aws ecr describe-image-scan-findings --repository-name <image-repository-name> --image-id imageTag=<image-tag> ``` While a detailed summary of results for each CVE is returned in the output, a summary sorted by critically is all that is needed to make a decision on the risk of the newly created container image which is found towards the end. ```json= { "HIGH": 18, "MEDIUM": 102, "LOW": 30, "UNDEFINED": 22, "INFORMATIONAL": 185, "CRITICAL": 3 } ``` The build phase can use [jq](https://stedolan.github.io/jq/) to process JSON outputs from the aws-cli to map the values needed. The aws-cli commands can be piped directly to jq expressions to apply filtering and select specific keys to output and in our case store as environment variables for further logic in the build phase. In the example below we apply a filter to only return the value of key pair under: `.imageScanFindings.findingSeverityCounts.CRITICAL` ```bash= aws ecr describe-image-scan-findings --repository-name $IMAGE_REPO_NAME --image-id imageTag=$CODEBUILD_BUILD_NUMBER | jq '.imageScanFindings.findingSeverityCounts.CRITICAL' ``` The output in this example will be ‘`3`’. ## Viewing Vulnerabilities In addition to the aws-cli output the the Amazon ECR console displays the findings from Amazon Inspector for the image. The image tag in the below reference is the CodeBuild Build Number, but you could also pass your CodeCommit commit ID to CodeBuild so that you can map the inclusion of the vulnerability back to when it started for full traceability. ![](https://hackmd.io/_uploads/HJS5lnfkp.png) Details shows us a chart overview of the scan findings and list that can be sorted or searched. ![](https://hackmd.io/_uploads/HkTsxhfkT.png) ![](https://hackmd.io/_uploads/SJlal2zJp.png) Amazon ECR and Amazon Inspector can share data with AWS Security Hub by [enabling the enhanced scanning tier](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-enhanced.html). By checking and removing the vulnerabilities during the build phase of a deployment pipeline, it moves the problem to the front of the pipeline and increasing your security posture, by allowing the finding to be ingested into Security Hub your security teams can have greater visibility into development operations. ## Build Phase In the example below AWS CodeBuild will be used for container image build in image build pipeline. A Buildspec yaml file details the steps to perform the scanning in the `post_build` phase starting line 18. (*Note: these steps could be adapted to any CI/CD build pipeline tool chain, not AWS CodeBuild specific.*). ```shell= version: 0.2 phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com build: commands: - echo Build number $CODEBUILD_BUILD_NUMBER - echo Build started on `date` - echo Building the Docker image... - docker build -t $IMAGE_REPO_NAME:$CODEBUILD_BUILD_NUMBER . - docker tag $IMAGE_REPO_NAME:$CODEBUILD_BUILD_NUMBER $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$CODEBUILD_BUILD_NUMBER post_build: commands: - echo Build completed on `date` - echo Pushing the Docker image... - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$CODEBUILD_BUILD_NUMBER - aws ecr start-image-scan --repository-name $IMAGE_REPO_NAME --image-id imageTag=$CODEBUILD_BUILD_NUMBER - aws ecr wait image-scan-complete --repository-name $IMAGE_REPO_NAME --image-id imageTag=$CODEBUILD_BUILD_NUMBER - aws ecr describe-image-scan-findings --repository-name $IMAGE_REPO_NAME --image-id imageTag=$CODEBUILD_BUILD_NUMBER >> scan_results.json - SCAN_SUMMARY=$(cat scan_results.json| jq '.imageScanFindings.findingSeverityCounts') - echo Summary of results - echo $SCAN_SUMMARY - CRITICAL=$(cat scan_results.json | jq -c '.imageScanFindings.findingSeverityCounts.CRITICAL') && HIGH=$(cat scan_results.json | jq -c '.imageScanFindings.findingSeverityCounts.HIGH') - if [ $CRITICAL != null ]; then echo "Vulnerabilties Found" && exit 1; fi ``` ## Pricing Basic scanning is available with no additional charge to Amazon ECR customers. Each container image may be scanned once per 24 hours with basic scanning. This can be enough to return the image scan JSON and stop your builds when your desired threshold is breached, but the results won’t be pushed to AWS Security Hub. For that we need enhanced scanning which is provided and billed through Amazon Inspector. ### Resources ECR Scanning https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ecr.html Viewing all vulnerabilities below the threshold will be pushed to AWS Security Hub. https://aws.amazon.com/blogs/containers/container-scanning-updates-in-amazon-ecr-private-registries-using-amazon-inspector/