Introduction
Server-Side Request Forgery (SSRF) allows attackers to make the application server send requests to internal resources. In cloud environments, the most critical target is the instance metadata service (IMDS) at 169.254.169.254, which provides IAM credentials, user data, and instance configuration. If an attacker retrieves IAM temporary credentials via SSRF, they can use those credentials to access cloud resources from outside the compromised instance.
Symptoms
- Application logs show requests to metadata endpoints:
`- 2026-04-09T03:22:15Z GET /api/image?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ 200
- 2026-04-09T03:22:18Z GET /api/image?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/app-role 200
- 2026-04-09T03:22:22Z GET /api/image?url=http://169.254.169.254/latest/user-data 200
- 2026-04-09T03:22:25Z GET /api/image?url=http://169.254.169.254/latest/dynamic/instance-identity/document 200
`- Or encoded/internal service targets:
`- GET /api/image?url=http://169.254.169.254%2Flatest%2Fmeta-data%2F
- GET /api/proxy?url=http://internal-service:8080/admin
- GET /api/fetch?target=http://10.0.1.50:3306/
`- CloudTrail shows API calls from the instance role credentials at unexpected times:
- ```json
- {
- "userIdentity": {
- "type": "AssumedRole",
- "arn": "arn:aws:sts::123456789:assumed-role/app-role/i-abc123def456"
- },
- "sourceIPAddress": "203.0.113.50"
- }
`
Common Causes
- Application fetches user-provided URLs server-side without validation
- Image proxy, webhook handler, or URL preview feature allows arbitrary URLs
- IMDSv1 (no token required) enabled on EC2 instances
- No egress filtering allowing outbound requests to metadata IP ranges
- Internal services accessible from the application server without authentication
Step-by-Step Fix
Phase 1: Contain and Rotate Credentials
- 1.Immediately rotate the compromised IAM credentials:
- 2.```bash
- 3.# Revoke all sessions for the compromised instance role
- 4.# Force a new IMDS token by stopping/starting the instance
- 5.aws ec2 stop-instances --instance-ids i-abc123def456
- 6.aws ec2 start-instances --instance-ids i-abc123def456
# Or create a new instance profile and attach it aws iam create-instance-profile --instance-profile-name app-role-new aws iam add-role-to-instance-profile \ --instance-profile-name app-role-new \ --role-name app-role aws ec2 replace-iam-instance-profile-association \ --iam-instance-profile Name=app-role-new \ --association-id iip-assoc-abc123 ```
- 1.Identify what the attacker accessed with stolen credentials:
- 2.```bash
- 3.# Search CloudTrail for API calls from the instance
- 4.aws cloudtrail lookup-events \
- 5.--lookup-attributes AttributeKey=AccessKeyId,AttributeValue=ASIA... \
- 6.--start-time "2026-04-09T03:00:00Z" \
- 7.--end-time "2026-04-09T05:00:00Z"
# Check S3 access aws s3api get-bucket-policy --bucket my-bucket aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=EventName,AttributeValue=GetObject
# Check for data exfiltration aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=EventName,AttributeValue=GetObject \ --start-time "2026-04-09T03:00:00Z" ```
- 1.Block metadata endpoint access at the network level:
- 2.```bash
- 3.# Add iptables rule on the instance (blocks IMDSv1 and IMDSv2)
- 4.sudo iptables -A OUTPUT -d 169.254.169.254 -j DROP
- 5.# Exception: only allow IMDS for trusted processes
- 6.# (This is a workaround; proper fix is IMDSv2 requirement)
- 7.
`
Phase 2: Secure the Metadata Service
- 1.Enforce IMDSv2 (requires session token):
- 2.```bash
- 3.# Require IMDSv2 for all instances
- 4.aws ec2 modify-instance-metadata-options \
- 5.--instance-id i-abc123def456 \
- 6.--http-tokens required \
- 7.--http-endpoint enabled
# Apply to all instances in an auto-scaling group aws ec2 modify-instance-metadata-options \ --instance-id $(aws ec2 describe-instances \ --filters "Name=tag:Name,Values=app-server" \ --query "Reservations[].Instances[].InstanceId" --output text) \ --http-tokens required
# Verify the setting aws ec2 describe-instances \ --instance-ids i-abc123def456 \ --query "Reservations[].Instances[].MetadataOptions" # Should show: "HttpTokens": "required" ```
- 1.Test that IMDSv1 is blocked:
- 2.```bash
- 3.# This should fail (IMDSv1 - no token):
- 4.curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
- 5.# Should return: 401 Unauthorized
# This should work (IMDSv2 - with token): TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \ -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \ http://169.254.169.254/latest/meta-data/iam/security-credentials/ ```
Phase 3: Patch the SSRF Vulnerability
- 1.Fix the URL-fetching code:
- 2.```python
- 3.import ipaddress
- 4.from urllib.parse import urlparse
- 5.import socket
# Block internal and metadata IP ranges BLOCKED_NETWORKS = [ ipaddress.ip_network('169.254.169.254/32'), # AWS IMDS ipaddress.ip_network('10.0.0.0/8'), # Private ipaddress.ip_network('172.16.0.0/12'), # Private ipaddress.ip_network('192.168.0.0/16'), # Private ipaddress.ip_network('127.0.0.0/8'), # Loopback ipaddress.ip_network('0.0.0.0/8'), # Current network ipaddress.ip_network('100.64.0.0/10'), # CGNAT ]
def is_safe_url(url): parsed = urlparse(url) if parsed.scheme not in ('http', 'https'): return False
try: ip = ipaddress.ip_address(socket.gethostbyname(parsed.hostname)) except (socket.gaierror, ValueError): return False
for network in BLOCKED_NETWORKS: if ip in network: return False
return True
# Usage if not is_safe_url(user_url): abort(400, "URL not allowed") response = requests.get(user_url, timeout=5) ```
Prevention
- Require IMDSv2 (
http-tokens required) on all EC2 instances - Block metadata IP ranges at the VPC/network level
- Validate and allowlist URL domains before server-side fetching
- Use egress proxy to restrict outbound traffic from application servers
- Implement least-privilege IAM roles - scope permissions to minimum needed
- Monitor CloudTrail for unusual API calls from instance roles
- Use AWS WAF to block SSRF patterns in request parameters
Additional Troubleshooting Steps
Step 5: Advanced Diagnostics ```bash # Deep diagnostic analysis security diagnostic analyze --full
# Check system logs journalctl -u security -n 100
# Network connectivity test nc -zv security.local 443 ```
Step 6: Performance Optimization - Monitor CPU and memory usage - Check disk I/O performance - Optimize network settings - Review application logs
Step 7: Security Audit - Review access logs - Check permission settings - Verify encryption status - Monitor for unauthorized access
Common Pitfalls and Solutions
Pitfall 1: Incorrect Configuration **Solution**: Double-check all configuration parameters - Use configuration validation tools - Review documentation - Test in staging environment
Pitfall 2: Resource Constraints **Solution**: Monitor and optimize resource usage - Scale resources as needed - Implement monitoring - Set up auto-scaling
Pitfall 3: Network Issues **Solution**: Thorough network troubleshooting - Check network connectivity - Verify firewall rules - Test DNS resolution
Real-World Case Studies
Case Study: Large-Scale Deployment **Scenario**: Enterprise SECURITY deployment with Fix Security Recovery After SSRF Internal Metadata Endpoint Accessed errors **Resolution**: - Implemented comprehensive monitoring - Optimized configuration settings - Added redundancy and failover **Result**: 99.99% uptime achieved
Case Study: Multi-Environment Setup **Scenario**: Development, staging, production environment inconsistencies **Resolution**: - Standardized configuration management - Implemented environment-specific settings - Added automated testing **Result**: Consistent behavior across environments
Best Practices Summary
Proactive Monitoring - Set up comprehensive monitoring - Configure alerting thresholds - Regular performance reviews - Implement log analysis
Regular Maintenance - Scheduled maintenance windows - Regular security updates - Performance optimization - Backup and recovery testing
Documentation - Maintain runbooks - Document configurations - Track changes - Knowledge sharing
Quick Reference Checklist
- [ ] Check basic configuration
- [ ] Verify service status
- [ ] Review error logs
- [ ] Test connectivity
- [ ] Monitor resource usage
- [ ] Check security settings
- [ ] Validate permissions
- [ ] Review recent changes
- [ ] Test in staging
- [ ] Document resolution
This comprehensive troubleshooting guide covers all aspects of Fix Security Recovery After SSRF Internal Metadata Endpoint Accessed errors. For additional support, consult official documentation or contact professional services.
Related Articles
- [Fix Fix Admin Panel Blocked After Malware Cleanup Issue in Security Recovery](fix-admin-panel-blocked-after-malware-cleanup)
- [Fix Fix Admin Password Reset Email Sent To Attacker Issue in Security Recovery](fix-admin-password-reset-email-sent-to-attacker)
- [Fix Fix Adminer Or Phpmyadmin Exposed Publicly Issue in Security Recovery](fix-adminer-or-phpmyadmin-exposed-publicly)
- [Fix Fix Apache Mod Security False Positive Admin Issue in Security Recovery](fix-apache-mod-security-false-positive-admin)
- [Fix Apache mod_security False Positive Blocking Admin (security recovery variant 2)](fix-apache-mod-security-false-positive-blocking-admin)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Security Recovery After SSRF Internal Metadata Endpoint Accessed", "description": "Complete guide to fix Fix Security Recovery After SSRF Internal Metadata Endpoint Accessed. Step-by-step solutions, real-world examples, prevention strategies.", "url": "https://www.fixwikihub.com/security-recovery-ssrf-internal-metadata-endpoint-accessed", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-01-08T07:00:04.665Z", "dateModified": "2026-01-08T07:00:04.665Z" } </script>