Guide · AWS GuardDuty · Lambda Protection
GuardDuty Lambda Protection for Serverless MCP Servers — Runtime Threat Monitoring
GuardDuty Lambda protection monitors the network activity of all Lambda functions in an account for connections to known threat infrastructure — cryptocurrency mining pools, command-and-control servers, Tor entry nodes, and IP ranges associated with data exfiltration — without requiring any code change or Lambda layer installation. The protection works by analyzing Lambda's internal network flow data rather than VPC flow logs, which means it covers both VPC-attached and public Lambda functions. For Lambda-based MCP servers the most important finding type is CryptoCurrency:Lambda/BitcoinTool, which indicates a Lambda function is making DNS queries to known mining pool domains — a reliable indicator of code injection via user-controlled tool call arguments being passed to shell commands. This cannot happen in pure JavaScript/Python MCP handlers that never call exec() or subprocess(), but is a real risk for MCPs that execute user-specified commands as part of their tool surface.
TL;DR
Enable Lambda protection via UpdateDetector with feature LAMBDA_NETWORK_LOGS. No agent or code change required — GuardDuty analyzes Lambda network flow at the service level. Cost: $0.20 per 1M Lambda invocations after the first 1M free per month. Key finding types: CryptoCurrency:Lambda/BitcoinTool (code injection indicator), Backdoor:Lambda/C&CActivity.B (C2 communication), UnauthorizedAccess:Lambda/MetadataDNSRebind (SSRF targeting instance metadata). Lambda-based MCP servers calling Anthropic/OpenAI APIs will generate initial false positives as "first-seen destinations" — add suppression filters. See the main GuardDuty guide for detector setup and the Lambda deployment guide for Lambda MCP architecture.
Enable Lambda protection
Lambda protection is a GuardDuty feature that must be explicitly enabled — it is not included in the base detector. Enabling applies to all Lambda functions in the account in the enabled region; there is no per-function selective coverage as of 2026.
# Enable Lambda network activity monitoring
aws guardduty update-detector \
--detector-id abc1234567890abcdef1234567890 \
--features '[
{
"Name": "LAMBDA_NETWORK_LOGS",
"Status": "ENABLED"
}
]'
# Verify Lambda protection status
aws guardduty get-detector \
--detector-id abc1234567890abcdef1234567890 \
--query 'Features[?Name==`LAMBDA_NETWORK_LOGS`]'
# Expected: [{"Name": "LAMBDA_NETWORK_LOGS", "Status": "ENABLED", ...}]
# For Organizations: enable Lambda protection on all member accounts
# (run in delegated admin account)
aws guardduty update-organization-configuration \
--detector-id \
--features '[
{
"Name": "LAMBDA_NETWORK_LOGS",
"AutoEnable": "ALL"
}
]'
Lambda protection pricing: first 1 million Lambda invocations per month per account are free. Above that, the cost is $0.20 per 1 million invocations. For an MCP server handling 100 requests/day (3,000/month), this is well within the free tier. For high-traffic MCP deployments (1M+ invocations/month), factor the cost into your security budget — it is typically less than 1% of Lambda compute cost for most workloads.
| Monthly invocations | GuardDuty Lambda cost | Typical MCP scale |
|---|---|---|
| 0–1M | Free | Development / small production (<33k requests/day) |
| 1M–10M | ~$1.80/month | Medium production (33k–333k requests/day) |
| 10M–100M | ~$18/month | Large production (333k–3.3M requests/day) |
| 100M+ | Volume pricing | High-scale MCP platform |
Lambda-specific finding types
GuardDuty generates Lambda-specific findings in the Lambda resource type category. The finding's resource.lambdaDetails field identifies the function; service.action.networkConnectionAction describes the suspicious connection.
| Finding type | Trigger | MCP context and response |
|---|---|---|
CryptoCurrency:Lambda/BitcoinTool | Lambda function making DNS queries to known cryptocurrency mining pool domains | High confidence code injection indicator — MCP tool handler passing user input to shell; disable function, inspect handler code for eval()/exec() patterns with user-controlled args |
Backdoor:Lambda/C&CActivity.B | Lambda function making network connections to known C2 server IPs or domains | Function compromised via injected dependency or supply-chain attack; disable function, audit recent package.json changes, inspect npm audit output |
UnauthorizedAccess:Lambda/MetadataDNSRebind | Lambda function making DNS queries that resolve to 169.254.169.254 (EC2 instance metadata endpoint via DNS rebinding) | SSRF attack via DNS rebinding — attacker is trying to reach metadata service from Lambda; inspect request handling for URL-fetch tools that accept user-controlled URLs |
UnauthorizedAccess:Lambda/TorClientError | Lambda function connecting to Tor entry guard nodes | Attacker attempting to anonymize exfiltration via Tor; block outbound connections in security group if Lambda is VPC-attached; review Lambda URL / API Gateway for injection vectors |
Execution:Lambda/SuspiciousNetworkActivity.B | Lambda function making unusual outbound connections — unexpected ports, destination countries, or IPs not previously seen | Low-severity, often a false positive for MCP servers making outbound API calls to new endpoints; create suppression filter if the destination is known-good |
UnauthorizedAccess:Lambda/MaliciousIPCaller.Custom | Lambda function called by a known-malicious IP address | Inbound traffic from threat actor — check if your MCP Lambda URL or API Gateway has proper auth; investigate caller IP in CloudTrail |
# Get Lambda finding details — identify which function and what connection
aws guardduty get-findings \
--detector-id abc1234567890abcdef1234567890 \
--finding-ids "lambda-finding-id" \
--query 'Findings[0].{
Type:Type,
Severity:Severity,
Function:Resource.LambdaDetails,
Connection:Service.Action.NetworkConnectionAction
}'
# LambdaDetails structure:
# {
# "FunctionName": "mcp-tool-handler",
# "FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:mcp-tool-handler",
# "FunctionVersion": "$LATEST",
# "Role": "arn:aws:iam::123456789012:role/mcp-tool-handler-role",
# "Tags": [{"Key": "Service", "Value": "mcp-api"}],
# "VpcConfig": {
# "SubnetIds": ["subnet-abc123"],
# "SecurityGroupIds": ["sg-def456"],
# "VpcId": "vpc-ghi789"
# }
# }
# NetworkConnectionAction structure:
# {
# "ConnectionDirection": "OUTBOUND",
# "Protocol": "UDP",
# "LocalPortDetails": {"Port": 53, "PortName": "DNS"},
# "RemoteIpDetails": {
# "IpAddressV4": "198.51.100.10",
# "Country": {"CountryName": "Netherlands"},
# "Organization": {"Asn": "12345", "AsnOrg": "Mining Pool ASN"}
# },
# "RemotePortDetails": {"Port": 53, "PortName": "DNS"}
# }
False positives in Lambda-based MCP servers
Lambda MCP servers making outbound API calls to LLM providers and external services will generate initial Execution:Lambda/SuspiciousNetworkActivity.B findings because GuardDuty uses a baseline period to learn normal behavior — connections to IP ranges not seen in the first 2 weeks of monitoring are flagged as "first-seen destinations." Create suppression filters for known-good destinations immediately after enabling Lambda protection to prevent noise from blocking real alerts.
# Suppress SuspiciousNetworkActivity for known Anthropic API IP range
# (Note: Anthropic uses CloudFront, so destination IPs vary — suppress by ASN or country is less reliable)
# Best approach: suppress by finding type + function name for AI provider calls
aws guardduty create-filter \
--detector-id abc1234567890abcdef1234567890 \
--name "mcp-llm-api-outbound-suppression" \
--action ARCHIVE \
--rank 1 \
--finding-criteria '{
"Criterion": {
"type": {
"Equals": ["Execution:Lambda/SuspiciousNetworkActivity.B"]
},
"resource.lambdaDetails.functionName": {
"Prefix": ["mcp-"]
}
}
}'
# More targeted: suppress only connections to specific ASN ranges
# Cloudflare (AS13335) hosts api.anthropic.com via Cloudflare; AWS AS16509 for Bedrock
aws guardduty create-filter \
--detector-id abc1234567890abcdef1234567890 \
--name "mcp-ai-provider-asn-suppression" \
--action ARCHIVE \
--rank 2 \
--finding-criteria '{
"Criterion": {
"type": {
"Equals": ["Execution:Lambda/SuspiciousNetworkActivity.B"]
},
"service.action.networkConnectionAction.remoteIpDetails.organization.asn": {
"Equals": ["13335", "16509", "14618"]
}
}
}'
# After the baseline period (2-3 weeks), SuspiciousNetworkActivity.B findings
# naturally decrease as GuardDuty learns your Lambda's normal outbound patterns.
# Keep targeted suppression for CryptoCurrency:Lambda/* and Backdoor:Lambda/* active —
# these are threat-intelligence-based (not behavioral) and have very low false-positive rates.
Do not suppress CryptoCurrency:Lambda/BitcoinTool or Backdoor:Lambda/C&CActivity.B — these are based on known threat intelligence (specific IP/domain threat feeds) with very low false-positive rates. If you see these findings for your production MCP function, treat them as confirmed security events, not noise.
Lambda protection vs. Lambda Insights and X-Ray
Lambda protection, Lambda Insights, and X-Ray serve different monitoring purposes for Lambda-based MCP servers. All three can run simultaneously without conflict.
| Tool | What it monitors | When to use for MCP |
|---|---|---|
| GuardDuty Lambda protection | Security anomalies: outbound connections to threat infrastructure, DNS rebinding attacks, Tor usage, crypto mining | Always enabled for production — detects post-compromise behavior at the network level |
| Lambda Insights | Performance: CPU, memory, disk I/O, network bytes, cold starts, duration | Enable when diagnosing performance issues in MCP tool handlers; useful for spotting memory leaks in long-running functions |
| AWS X-Ray | Tracing: request paths, downstream AWS service call latency, errors, fault percentages | Enable for tracing MCP tool call chains through DynamoDB/S3/Bedrock; see X-Ray Lambda guide for MCP tracing setup |
| CloudWatch Lambda Logs | Application: structured logs from your MCP handler code | Always — primary debugging surface for MCP errors |
GuardDuty Lambda protection operates below the function level — at the Lambda service network layer — and does not increase Lambda function cold start time, execution duration, or memory usage. It has zero performance impact on your MCP server's response latency.
Failure modes reference
| Failure | Symptom | Fix |
|---|---|---|
| Lambda protection enabled but no findings generated | Known-suspicious Lambda invocations not surfacing as findings | Lambda protection has a 2-week baseline learning period; threat-intelligence findings (CryptoCurrency, Backdoor) appear immediately; behavioral findings (SuspiciousNetworkActivity) require baseline; verify feature is ENABLED not PENDING |
| Excessive SuspiciousNetworkActivity.B findings on deploy | Every Lambda invocation during first week generates findings | Expected during baseline learning period; create targeted suppression filters for known-good destinations; findings naturally decrease after baseline is established |
| Finding shows wrong function version | Finding references $LATEST but function has published versions | Lambda protection uses the version active at invocation time; if function uses $LATEST in production, GuardDuty correctly shows $LATEST; publish and alias versions to pin production traffic to specific versions |
| MetadataDNSRebind finding for legitimate IMDS access | Lambda function legitimately calling 169.254.169.254 for instance metadata (not via SSRF) | Lambda functions can access instance metadata via IMDSv2 for region detection; the finding is generated when DNS resolves to this IP — suppress if your function legitimately calls IMDS; review if unexpected |
| Lambda protection cost higher than expected | Monthly bill shows unexpected GuardDuty Lambda charges | Lambda protection charges per invocation across ALL functions — check which high-invocation functions (e.g., API Gateway-connected) are driving volume; consider cost vs. risk tradeoff for non-MCP functions |