28.5 ECR Enhanced Scanning: Inspector Integration for CVE Detection
Right, so you’ve got your images in ECR. Good for you. But let’s be honest, you’re not just pushing “Hello World” apps in there, are you? You’re running actual software, which means you’re inheriting other people’s problems, usually in the form of Common Vulnerabilities and Exposures (CVEs). Manually scanning for these is a chore fit for an intern, not you. This is where ECR’s Enhanced Scanning feature comes in, and it’s one of the few AWS services that feels like it actually does the work for you without a constant, nagging guilt trip about configuration.
Here’s the deal: basic scanning uses open-source Clair under the hood. It’s fine. Enhanced Scanning, however, hands the baton to AWS Inspector. This is a massive upgrade. Inspector is a proper vulnerability management service that doesn’t just check a list; it provides a risk score (their own CVSS v3 score), tells you the exploitability, and constantly updates its knowledge base with the latest threats. It’s the difference between a guard with a flashlight and one with thermal imaging and a direct line to the CIA.
How It Actually Works (The Magic, Demystified)
You turn it on. I’m serious, it’s that simple. But since you’re a professional, let’s peek behind the curtain. When you push an image, ECR doesn’t just sit there. It triggers an event (via EventBridge) that tells Inspector V2: “Hey, scan this.” Inspector then pulls the image layer-by-layer, unpacks it like a digital onion, and meticulously catalogs every package in every layer—not just the operating system packages (like in apt or yum), but language-level dependencies for Python, Node.js, Java, and more. This is the killer feature. Finding a vulnerability in your base OS libssl is one thing; finding one buried twelve layers deep in your node_modules/left-pad dependency is what saves your bacon.
The results are pushed back to ECR and just… appear. You don’t need to set up a separate Inspector dashboard, which is a relief because nobody needs another dashboard.
Enabling This Party Trick
You can do it via the console with a few clicks (go to your registry settings, enable it), but we both live in the terminal, so let’s do it properly with the AWS CLI. The command is straightforward, but note the scanType parameter. This is where you choose your weapon.
# Enable enhanced scanning for your entire registry
aws ecr put-registry-scanning-configuration \
--scan-type ENHANCED \
--rules '[{
"scanFrequency": "SCAN_ON_PUSH",
"repositoryFilters": [{
"filter": "*",
"filterType": "WILDCARD"
}]
}]'
The scanFrequency of SCAN_ON_PUSH is what you want. It means every time you docker push, the scan kicks off immediately. The alternative is CONTINUOUS_SCAN, which re-scans existing images in your repository every 24 hours if a new CVE is published that affects them. You should probably enable both, but SCAN_ON_PUSH is non-negotiable.
Reading the Tea Leaves (Understanding Scan Findings)
The output is where Inspector earns its keep. Don’t just look for a red “FAILURE” message. Drill into the findings. The CLI gives you a JSON blob of glory. Let’s query it.
# Describe the image scan findings for a specific image tag
aws ecr describe-image-scan-findings \
--repository-name my-app-repo \
--image-id imageTag=latest \
--output json
Now, look for the findingSeverityCounts and the enhancedFindings array. This is the gold. A basic scan might tell you there’s a CVE. An enhanced finding tells you the CVSS score, the exploitability (“NETWORK” vs “LOCAL”), if there’s a known exploit (“ExploitAvailable: YES” – a very bad day), and even suggests a fix. The severity levels are CRITICAL, HIGH, MEDIUM, LOW, and INFORMATIONAL.
Here’s a snippet of what a nasty finding looks like:
{
"awsAccountId": "123456789012",
"description": "A nasty vulnerability in libc that allows remote code execution",
"findingArn": "arn:aws:inspector2:us-east-1:123456789012:finding/abc123...",
"firstObservedAt": "2023-10-26T18:35:39.431Z",
"inspectorScore": 9.8,
"inspectorScoreDetails": {
"adjustedCvss": {
"score": 9.8,
"scoringVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
}
},
"packageVulnerabilityDetails": {
"cvss": [ ... ],
"referenceUrls": [ "https://nvd.nist.gov/vuln/detail/CVE-2023-12345" ],
"relatedVulnerabilities": [ ... ],
"source": "nvd",
"sourceUrl": "https://nvd.nist.gov/",
"vulnerabilityId": "CVE-2023-12345",
"vulnerablePackages": [
{
"arch": "amd64",
"epoch": 0,
"filePath": "usr/lib/x86_64-linux-gnu/libc-2.31.so",
"name": "libc6",
"packageManager": "OS",
"release": "ubuntu0.20.04.1",
"sourceLayerHash": "sha256:abc123...",
"version": "2.31-0ubuntu9.9"
}
]
},
"remediation": {
"recommendation": {
"text": "Update the package libc6 to version 2.31-0ubuntu9.10 or later."
}
},
"severity": "CRITICAL",
"status": "ACTIVE",
"title": "CVE-2023-12345 - libc6",
"type": "PACKAGE_VULNERABILITY"
}
See that? "inspectorScore": 9.8, "severity": "CRITICAL", and "ExploitAvailable": "YES" (not shown here but often present). This isn’t a suggestion; it’s a five-alarm fire. The scoringVector AV:N means it’s network exploitable. Fix it. Now.
The Rough Edges and Pitfalls (Because Nothing is Perfect)
- The Speed vs. Security Trade-off: The scan happens after the push. It’s fast, but not instantaneous. If your CI/CD pipeline is set to automatically deploy on a successful push, it might deploy a vulnerable image for a few minutes before the scan finishes and fails. You need to integrate scan results into your deployment logic, perhaps using EventBridge to trigger a Lambda function that checks the scan status before promoting the image. This is the “well, actually…” part of the feature.
- The Bill Comes Due: Enhanced Scanning is a feature of Inspector V2. Inspector V2 costs money. It’s not exorbitant, but it’s not free. You pay per container image scan. Check the AWS pricing page before you enable it on a registry that gets 500 pushes an hour.
- The Ignore List is Your Friend: You will get
INFORMATIONALfindings for things that don’t matter in your specific context. A vulnerability in a binary your application never calls. You can create a repository-specific ignore rule to mute these findings permanently. Use this power wisely. Don’t ignoreCRITICALfindings because you’re lazy. That’s how breaches happen.
# Create a lifecycle policy to ignore a specific CVE across your repo
# You'd typically do this in the console, but the principle is there.
The best practice? Bake scan results into your CI/CD pipeline. Break the build if there are CRITICAL or HIGH findings. Let MEDIUM and LOW through but require manual review. This moves security from being a gate at the end to being an integral part of your development process, which is exactly where it should be.