Guide · AWS Inspector · Lambda Scanning

AWS Inspector Lambda Scanning — Package Vulnerabilities, Code Scanning, and Layer Coverage

Inspector Lambda scanning has two distinct modes with separate pricing and separate activation: standard scanning (PACKAGE_VULNERABILITY — $0.30/function/month) detects known CVEs in packages bundled in the function's deployment package and all attached Lambda Layers; code scanning (CODE_VULNERABILITY — additional $0.30/function/month) runs CodeGuru Security SAST analysis on the function's source code to detect injection flaws, cryptographic misuse, and hard-coded credentials. Most MCP server teams should start with standard scanning only — it covers the dependency supply chain without requiring access to source code — and evaluate code scanning separately if SAST is not already handled in CI. Neither scan type requires an agent; Inspector pulls the function package from the control plane without affecting runtime performance or cold start times.

TL;DR

Enable with aws inspector2 enable --resource-types LAMBDA (standard) and optionally LAMBDA_CODE (SAST). Inspector scans on function create/update and rescans on new CVE publication — no agents, no runtime overhead. For Inspector overview see the Inspector overview. For EC2 scanning see the EC2 guide. For ECR scanning see the ECR guide. For finding management see the findings guide.

Standard vs. code scanning

FeatureStandard scanning (LAMBDA)Code scanning (LAMBDA_CODE)
Finding typePACKAGE_VULNERABILITYCODE_VULNERABILITY
What is analyzedPackage manifests and lock files in the function deployment package and attached layersSource code in the function deployment package via CodeGuru Security SAST
Languages coveredPython, Node.js, Ruby, Java, Go, .NETPython, Java, JavaScript/TypeScript, C# (CodeGuru supported languages)
Cost$0.30/function/month$0.30/function/month (additive to standard)
Container image functionsOnly via ECR enhanced scanning pathNot supported — .zip only
Additional service dependencyNoneCodeGuru Security must be active in the account
Rescan on new CVEYesNo — code findings are static; rescan only on function update

Enabling Lambda scanning

Lambda scanning requires no configuration beyond enabling it in Inspector. Once enabled, all functions in the region are scanned automatically — there is no per-function opt-in or IAM role to attach to the function.

# Enable standard Lambda scanning (package vulnerabilities)
aws inspector2 enable \
  --resource-types LAMBDA \
  --region us-east-1

# Enable both standard and code scanning
aws inspector2 enable \
  --resource-types LAMBDA LAMBDA_CODE \
  --region us-east-1

# Verify Lambda scanning is active
aws inspector2 batch-get-account-status \
  --account-ids "$(aws sts get-caller-identity --query Account --output text)" \
  --query 'accounts[0].resourceState.lambda'

The initial scan of all existing Lambda functions in the region typically completes within minutes for standard scanning. Code scanning may take longer for functions with large deployment packages. After the initial scan, rescans are triggered by function updates (deploy) and by new CVE publications (standard scanning only — code scanning does not rescan unless the function is updated).

Package coverage: what Inspector reads from Lambda functions

Inspector reads the function deployment package (.zip) from the Lambda service — it does not need to invoke the function or access its environment variables. The package manifests Inspector looks for within the .zip:

RuntimeFiles Inspector readsCommon pitfall
Pythonsite-packages/*/METADATA, requirements.txtIf packages are installed with --target . instead of --target ./python, the metadata path differs from a standard site-packages layout — Inspector should still detect it, but verify with ListFindings after deploy
Node.jsnode_modules/*/package.jsonTree-shaken bundles (esbuild, webpack) eliminate node_modules — Inspector cannot scan what was bundled away; you get zero findings, which is both good (smaller attack surface) and a gap (can't confirm CVE-free)
Javapom.xml, fat JAR manifestsUber-JARs shaded with Maven Shade plugin — Inspector extracts nested JARs; shading that renames packages breaks CVE matching
Rubygems/ directory, Gemfile.lockLambda layers used for gems must have the standard gems/ directory structure
GoBinary GOPATH metadata embedded in compiled binaryGo binaries compiled with -ldflags="-w -s" strip debug info — Inspector may not detect Go module versions

The bundled-dependency gap is the most common issue for modern Node.js MCP servers using esbuild or webpack: your node_modules is compiled away into a single bundle, so Inspector sees no npm packages to scan. This is actually a security benefit (reduced attack surface), but you need a separate tool in CI (e.g., Snyk, npm audit, Grype) to verify your dependencies before bundling.

Lambda Layer scanning

When a Lambda function has layers attached, Inspector scans the packages in all attached layers as part of the function scan — the function and its layers are analyzed together, and findings reference the specific layer or function package where the vulnerable package was found.

# View findings that originated in a Lambda Layer vs the function package
aws inspector2 list-findings \
  --filter-criteria '{
    "lambdaFunctionName": [{"comparison":"EQUALS","value":"my-mcp-handler"}],
    "findingType": [{"comparison":"EQUALS","value":"PACKAGE_VULNERABILITY"}]
  }' \
  --query 'findings[].{Score:inspectorScore,CVE:packageVulnerabilityDetails.vulnerabilityId,Package:packageVulnerabilityDetails.vulnerablePackages[0].name,LayerArn:packageVulnerabilityDetails.vulnerablePackages[0].sourceLayerArn}' \
  --output table

The sourceLayerArn field distinguishes layer-origin findings from function-package findings. If the vulnerable package is in a shared layer used by many functions, fixing the layer version (update to the patched layer ARN and deploy all functions that reference it) resolves the finding for all affected functions simultaneously.

If you use the AWS SDK for Python (boto3) layer or similar AWS-managed layers, Inspector will report package vulnerabilities in those layers too. AWS-managed layers are updated by AWS; you do not control the layer version. For unresolved CVEs in AWS-managed layers, create a suppression rule — AWS will update the layer on their schedule. For customer-managed layers, you are responsible for the update.

Code scanning (SAST via CodeGuru Security)

Lambda code scanning runs CodeGuru Security SAST analysis on the function's source code within the deployment package. It detects:

# View code vulnerability findings for a Lambda function
aws inspector2 list-findings \
  --filter-criteria '{
    "lambdaFunctionName": [{"comparison":"EQUALS","value":"my-mcp-handler"}],
    "findingType": [{"comparison":"EQUALS","value":"CODE_VULNERABILITY"}]
  }' \
  --query 'findings[].{Score:inspectorScore,Title:title,File:codeVulnerabilityDetails.filePath.fileName,Line:codeVulnerabilityDetails.filePath.startLine,Type:codeVulnerabilityDetails.cweIds[0]}' \
  --output table

Code scanning findings include the file name and line number of the vulnerable code within the deployment package. For MCP servers handling tool call inputs from LLM agents, injection detection is particularly relevant — any code path that constructs SQL queries or shell commands from tool call arguments is a high-value target for code scanning.

Code scanning does not rescan unless the function is updated — it is a point-in-time SAST check, not a continuous monitor. New findings only appear when you deploy a new function version. This is different from standard package scanning, which can produce new findings on unchanged deployed functions when CVEs are published.

Rescan triggers for Lambda

TriggerStandard scanningCode scanning
Function created or updated (new deploy)Yes — within minutesYes — within 15 minutes
New CVE published matching installed packageYes — automatic, no deploy neededNo — code findings are static
Layer version updated on functionYes — layer packages re-scannedYes — if code references changed
Inspector initially enabled in accountYes — initial scan of all functionsYes — initial SAST of all .zip functions

The practical implication: a Lambda function that was deployed months ago and has not been updated can accumulate new PACKAGE_VULNERABILITY findings as new CVEs are published against its bundled dependencies. Schedule regular function deployments (even no-op deploys) as part of your security cadence if you have long-lived Lambda functions — this also triggers a fresh code scan confirming no new CODE_VULNERABILITY findings were introduced.

Container image Lambda functions

Lambda functions deployed as container images (using --package-type Image) are not scanned by the Lambda scanning path. They are scanned via the ECR enhanced scanning path when the image is pushed to ECR — enabling --resource-types LAMBDA does not provide coverage for image-based functions. Enable --resource-types ECR and switch the ECR repository to enhanced scanning to cover image-based Lambda functions.

# Verify which of your Lambda functions are .zip vs image-based
aws lambda list-functions \
  --query 'Functions[].{Name:FunctionName,PackageType:PackageType,Runtime:Runtime}' \
  --output table

# For image-based functions, check ECR coverage
aws inspector2 list-coverage \
  --filter-criteria '{"resourceType":[{"comparison":"EQUALS","value":"AWS_ECR_CONTAINER_IMAGE"}]}' \
  --query 'coveredResources[?contains(resourceId, `lambda`)].{Id:resourceId,Status:scanStatus.statusCode}' \
  --output table

Failure modes reference

FailureSymptomFix
Zero findings for Node.js functionsInspector enabled, function deployed, no PACKAGE_VULNERABILITY findingsFunction uses a bundled build (esbuild/webpack) — node_modules not in package; use CI-side dependency scanning instead; Inspector finding zero is accurate
No CODE_VULNERABILITY findings despite LAMBDA_CODE enabledCode scanning enabled but no SAST findings appearCodeGuru Security must also be active; container-image functions not supported; only Python/Java/JS/TS/C# analyzed; function code may be minified/compiled (not raw source)
Layer findings not attributed to specific layersourceLayerArn is null in findingsPackage is in the function package itself, not a layer — the field is only populated for layer-origin packages
Findings persist after patching a packageUpdated package version in requirements.txt but finding still ACTIVEDeploy a new function version to trigger rescan; Inspector scans the deployed package, not the source repository
Image Lambda INACTIVE in Lambda coverageListCoverage shows image-based function as INACTIVEExpected — image functions are covered via ECR path, not Lambda path; check ECR coverage for the function's image URI