Ssrf on Aws
How SSRF Manifests in AWS
Server-Side Request Forgery (SSRF) in AWS environments presents unique attack vectors due to the platform's extensive service ecosystem and metadata endpoints. The most critical AWS-specific SSRF target is the Instance Metadata Service (IMDS), accessible at http://169.254.169.254. When attackers can control URLs in your application, they can craft requests to this internal endpoint to extract IAM credentials, configuration data, or even launch AWS CLI commands.
A common AWS SSRF pattern involves EC2 metadata access. Consider this vulnerable Node.js code using the AWS SDK:
const AWS = require('aws-sdk');
const https = require('https');
exports.handler = async (event) => {
const url = event.queryStringParameters.url; // User-controlled
// Vulnerable: attacker can set url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
const response = await https.get(url);
return {
statusCode: 200,
body: JSON.stringify(response.body)
};
};
Attackers can exploit this by requesting http://169.254.169.254/latest/meta-data/iam/security-credentials/[ROLE_NAME], which returns temporary IAM credentials with potentially broad permissions. These credentials can then be used to access S3 buckets, DynamoDB tables, or other AWS resources.
Another AWS-specific SSRF vector involves AWS SDK configuration endpoints. When the SDK cannot find credentials through standard means, it attempts to fetch them from IMDS. An SSRF vulnerability could allow an attacker to intercept SDK initialization:
# Attacker's crafted request
GET /api/endpoint?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/my-role HTTP/1.1
ECS and EKS environments introduce additional SSRF risks through their service discovery mechanisms. Container workloads often communicate using internal AWS service endpoints that shouldn't be accessible externally. An SSRF vulnerability could allow an attacker to access:
- AWS Secrets Manager at
https://secretsmanager.[region].amazonaws.com - AWS Parameter Store at
https://ssm.[region].amazonaws.com - Internal service endpoints within your VPC
The CVE-2022-24013 vulnerability in the AWS CLI demonstrates how SSRF can lead to credential exposure. The CLI attempts to fetch credentials from IMDS without proper validation, allowing attackers to intercept credential retrieval through SSRF.
AWS-Specific Detection
Detecting SSRF vulnerabilities in AWS requires both static code analysis and runtime scanning. The Instance Metadata Service provides several endpoints that should never be accessible from user-controlled inputs:
# Critical IMDS endpoints
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/identity-credentials/
http://169.254.169.254/latest/dynamic/instance-identity/
middleBrick's AWS-specific SSRF detection scans for these patterns automatically. The scanner tests for SSRF by attempting to access restricted AWS endpoints and analyzing responses for credential leakage or metadata exposure. Unlike generic scanners, middleBrick understands AWS-specific attack patterns and validates whether your application properly sanitizes URLs before making outbound requests.
For code-level detection, use AWS's own security tools. Amazon Inspector can identify SSRF vulnerabilities by analyzing network traffic patterns and detecting when your application makes unexpected outbound requests to internal AWS endpoints. The AWS Security Hub aggregates findings from multiple services, including SSRF detection from Inspector.
Runtime detection requires monitoring for unusual outbound traffic patterns. AWS WAF can be configured to block requests to known internal AWS endpoints:
{
"AWSManagedRulesCommonRuleSet": {
"Name": "AWSManagedRulesCommonRuleSet",
"ScopeDownStatement": {
"NotStatement": {
"Statement": {
"ByteMatchStatement": {
"FieldToMatch": {
"UriPath": {}
},
"PositionalConstraint": "Contains",
"SearchString": "169.254.169.254",
"TextTransformations": [
{
"Priority": 0,
"Type": "Lowercase"
}
]
}
}
}
}
}
}
CloudTrail logging provides forensic capabilities for SSRF detection. Monitor for API calls that shouldn't occur from your application context, such as unexpected S3 access or IAM operations. Set up CloudWatch alarms for unusual credential usage patterns that might indicate SSRF exploitation.
AWS-Specific Remediation
Remediating SSRF in AWS environments requires defense-in-depth. Start with input validation using AWS-native libraries. The AWS SDK provides built-in protection against SSRF when properly configured:
const AWS = require('aws-sdk');
const https = require('https');
// Safe URL validation for AWS environments
function validateUrl(url) {
const urlObject = new URL(url);
// Block internal AWS endpoints
if (urlObject.hostname === '169.254.169.254') {
throw new Error('Internal AWS endpoints are not allowed');
}
// Block AWS-specific domains
if (urlObject.hostname.endsWith('.amazonaws.com')) {
throw new Error('AWS service endpoints are not allowed');
}
// Block private IP ranges
const ip = urlObject.hostname;
const privateRanges = [
/^10\./,
/^172\.(1[6-9]|2[0-9]|3[0-1])\./,
/^192\.168\./,
/^127\./
];
if (privateRanges.some(range => range.test(ip))) {
throw new Error('Private IP addresses are not allowed');
}
return urlObject;
}
// Use AWS SDK with proper credential handling
const s3 = new AWS.S3({
region: process.env.AWS_REGION,
credentials: new AWS.SharedIniFileCredentials({profile: 'default'})
});
exports.handler = async (event) => {
try {
const url = validateUrl(event.queryStringParameters.url);
// Safe request using AWS SDK or properly configured HTTP client
const response = await https.get({
hostname: url.hostname,
path: url.pathname,
port: url.port || (url.protocol === 'https:' ? 443 : 80),
rejectUnauthorized: true
});
return {
statusCode: 200,
body: JSON.stringify(response.body)
};
} catch (error) {
return {
statusCode: 400,
body: JSON.stringify({error: error.message})
};
}
};
Implement IMDSv2 for enhanced protection. Version 2 requires a token for metadata access, making SSRF exploitation significantly harder:
# Enable IMDSv2 on EC2 instances
aws ec2 modify-instance-metadata-options \
--instance-id i-1234567890abcdef0 \
--http-tokens required \
--http-put-response-hop-limit 1
Use AWS Network Firewall to create rules that block SSRF attempts at the network level:
{
"RulesSource": {
"RulesString": "alert tcp any any -> any 80 (content:\"169.254.169.254\"; sid:1000001;)",
"RulesSourceList": {
"TargetList": ["169.254.169.254"],
"GeneratedRulesType": "ALLOWLIST"
}
}
}
For containerized workloads, use AWS App Mesh with strict service-to-service communication policies. This prevents containers from making unauthorized outbound requests to internal AWS services:
apiVersion: appmesh.aws/amazonaws.com/v1beta1
kind: VirtualNode
metadata:
name: frontend
spec:
listeners:
- portMapping:
port: 8080
protocol: http
backends:
- virtualService:
virtualServiceName: "protected-service.default.svc.cluster.local"
networking:
serviceDiscovery:
dns:
hostname: frontend.default.svc.cluster.local
accessLogging:
file:
path: "/dev/stdout"
format: "{\"timestamp\": \"%s\", \"destination\": \"%p\", \"source\": \"%s\"}"
Related CWEs: ssrf
| CWE ID | Name | Severity |
|---|---|---|
| CWE-918 | Server-Side Request Forgery (SSRF) | CRITICAL |
| CWE-441 | Unintended Proxy or Intermediary (Confused Deputy) | HIGH |