Security Group Allows Internet Access to Memcached Ports
Overview
This check verifies that your AWS security groups do not allow unrestricted inbound access from the internet (0.0.0.0/0 or ::/0) to Memcached port 11211.
Memcached is a popular in-memory caching system used to speed up web applications. It should never be directly accessible from the public internet.
Risk
Exposing Memcached to the internet creates serious security vulnerabilities:
- DDoS amplification attacks: Attackers can abuse publicly accessible Memcached servers to launch massive distributed denial-of-service attacks. Memcached amplification attacks have caused some of the largest DDoS incidents on record.
- Unauthorized data access: Memcached has no built-in authentication. Anyone who can connect can read and write cached data.
- Data exfiltration: Sensitive application data stored in cache (session tokens, user data, API responses) can be stolen.
- Service disruption: Attackers can flush your cache or inject malicious data, breaking your application.
This is a high severity finding that should be remediated immediately.
Remediation Steps
Prerequisites
You need:
- AWS Console access with permissions to modify security groups
- Knowledge of which applications legitimately need to access your Memcached instances
Required IAM permissions
Your IAM user or role needs these permissions:
ec2:DescribeSecurityGroupsec2:DescribeSecurityGroupRulesec2:RevokeSecurityGroupIngressec2:AuthorizeSecurityGroupIngress
AWS Console Method
Step 1: Identify the Offending Security Groups
- Go to the EC2 Console in us-east-1
- Click Security Groups in the left sidebar (under Network & Security)
- For each security group, check the Inbound rules tab
- Look for rules that match ALL of these criteria:
- Source is
0.0.0.0/0or::/0 - Port range includes
11211 - Protocol is
TCPorAll traffic
- Source is
Step 2: Remove the Unrestricted Rule
- Select the security group with the problematic rule
- Click the Inbound rules tab
- Click Edit inbound rules
- Find the rule allowing internet access to port 11211
- Click Delete (the X button) next to that rule
- Click Save rules
Step 3: Add a Restricted Rule (if needed)
If legitimate services need to access Memcached:
- Click Edit inbound rules again
- Click Add rule
- Configure the rule:
- Type: Custom TCP
- Port range: 11211
- Source: Choose one of these safer options:
- A specific security group (recommended): Select the security group of your web/app servers
- A specific IP range: Enter a private CIDR block like
10.0.0.0/8or172.16.0.0/12
- Add a description like "Memcached access from app servers"
- Click Save rules
Important: Never use 0.0.0.0/0 or ::/0 as the source for Memcached access.
AWS CLI (optional)
Identify Security Groups with Unrestricted Memcached Access
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=11211" \
"Name=ip-permission.to-port,Values=11211" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table
Also check for IPv6 unrestricted access:
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=11211" \
"Name=ip-permission.to-port,Values=11211" \
"Name=ip-permission.ipv6-cidr,Values=::/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table
Remove the Unrestricted Rule
Replace <security-group-id> with the actual security group ID:
# Remove IPv4 unrestricted rule
aws ec2 revoke-security-group-ingress \
--group-id <security-group-id> \
--protocol tcp \
--port 11211 \
--cidr 0.0.0.0/0 \
--region us-east-1
# Remove IPv6 unrestricted rule (if applicable)
aws ec2 revoke-security-group-ingress \
--group-id <security-group-id> \
--protocol tcp \
--port 11211 \
--cidr ::/0 \
--region us-east-1
Add a Restricted Rule
Allow access only from a specific security group (recommended):
aws ec2 authorize-security-group-ingress \
--group-id <memcached-security-group-id> \
--protocol tcp \
--port 11211 \
--source-group <app-server-security-group-id> \
--region us-east-1
Or allow access from a specific private CIDR:
aws ec2 authorize-security-group-ingress \
--group-id <security-group-id> \
--protocol tcp \
--port 11211 \
--cidr 10.0.0.0/8 \
--region us-east-1
CloudFormation (optional)
This template creates a secure security group for Memcached that only allows access from a specified source security group:
AWSTemplateFormatVersion: '2010-09-09'
Description: Secure security group for Memcached instances
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC where the security group will be created
SourceSecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Description: Security group ID of instances that need Memcached access (e.g., app servers)
Resources:
MemcachedSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: memcached-secure-sg
GroupDescription: Security group for Memcached - restricted access only
VpcId: !Ref VpcId
SecurityGroupIngress:
- Description: Memcached access from app servers only
IpProtocol: tcp
FromPort: 11211
ToPort: 11211
SourceSecurityGroupId: !Ref SourceSecurityGroupId
Tags:
- Key: Name
Value: memcached-secure-sg
Outputs:
SecurityGroupId:
Description: ID of the Memcached security group
Value: !Ref MemcachedSecurityGroup
Export:
Name: MemcachedSecurityGroupId
Deploy with:
aws cloudformation deploy \
--template-file memcached-security-group.yaml \
--stack-name memcached-secure-sg \
--parameter-overrides \
VpcId=vpc-xxxxxxxxx \
SourceSecurityGroupId=sg-xxxxxxxxx \
--region us-east-1
Note: After creating this new security group, you need to:
- Associate it with your Memcached EC2 instances or ElastiCache cluster
- Remove the old insecure security group from those resources
Terraform (optional)
variable "vpc_id" {
description = "VPC ID where the security group will be created"
type = string
}
variable "source_security_group_id" {
description = "Security group ID of instances that need Memcached access"
type = string
}
# Secure security group for Memcached
resource "aws_security_group" "memcached" {
name = "memcached-secure-sg"
description = "Security group for Memcached - restricted access only"
vpc_id = var.vpc_id
tags = {
Name = "memcached-secure-sg"
}
}
# Allow Memcached access only from specified source security group
resource "aws_security_group_rule" "memcached_ingress" {
type = "ingress"
from_port = 11211
to_port = 11211
protocol = "tcp"
description = "Memcached access from app servers only"
security_group_id = aws_security_group.memcached.id
source_security_group_id = var.source_security_group_id
}
output "security_group_id" {
description = "ID of the Memcached security group"
value = aws_security_group.memcached.id
}
Deploy with:
terraform init
terraform plan \
-var="vpc_id=vpc-xxxxxxxxx" \
-var="source_security_group_id=sg-xxxxxxxxx"
terraform apply \
-var="vpc_id=vpc-xxxxxxxxx" \
-var="source_security_group_id=sg-xxxxxxxxx"
Verification
After remediation, verify the security group no longer allows public access:
- Go to EC2 Console > Security Groups
- Select the remediated security group
- Check the Inbound rules tab
- Confirm there are no rules with:
- Source
0.0.0.0/0or::/0 - Port
11211
- Source
Also verify your application still works:
- Test that your application can still connect to Memcached
- Check application logs for connection errors
- Monitor your caching metrics to ensure cache hits are occurring
CLI verification commands
Verify no security groups allow unrestricted Memcached access:
# Check for IPv4 unrestricted access
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=11211" \
"Name=ip-permission.to-port,Values=11211" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].GroupId' \
--output text
# Check for IPv6 unrestricted access
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=11211" \
"Name=ip-permission.to-port,Values=11211" \
"Name=ip-permission.ipv6-cidr,Values=::/0" \
--query 'SecurityGroups[*].GroupId' \
--output text
If both commands return empty output, no security groups have unrestricted Memcached access.
Verify the specific security group rules:
aws ec2 describe-security-group-rules \
--region us-east-1 \
--filters "Name=group-id,Values=<security-group-id>" \
--query 'SecurityGroupRules[?FromPort==`11211`]'
Additional Resources
- AWS Documentation: Security Group Rules
- AWS Documentation: Control Traffic to Resources Using Security Groups
- Memcached DDoS Amplification Attack Explained
- AWS Security Best Practices: Network Security
- Trend Micro: Check for Unrestricted Memcached Access
Notes
-
No authentication: Memcached does not have built-in authentication. Network-level security (security groups, private subnets) is your only protection.
-
Use ElastiCache: Consider using Amazon ElastiCache for Memcached instead of self-managed instances. ElastiCache provides additional security features and can only be deployed in private subnets.
-
Private subnets: Best practice is to run Memcached instances in private subnets with no internet gateway route, in addition to security group restrictions.
-
UDP port 11211: This check focuses on TCP, but Memcached also uses UDP port 11211. Ensure both protocols are restricted. UDP-based Memcached amplification attacks are particularly dangerous.
-
Audit all security groups: The problematic rule might exist in multiple security groups. Review all security groups in your account, not just those currently attached to Memcached instances.
-
Application testing: Before removing rules in production, test in a staging environment to ensure your applications can still connect using the new restricted rules.
-
VPC Flow Logs: Enable VPC Flow Logs to monitor network traffic and detect any unauthorized connection attempts to your Memcached instances.