Insecure Access Control
Fixing Insecure Access Control
About Insecure Access Control
What is improper access control?
Improper access control is a vulnerability that occurs when a system does not properly restrict or enforce access to resources, such as files, directories, network resources, or application functions.
Examples of improper access control vulnerabilities include:
- Weak access controls: When access controls are weak or easily bypassed, attackers can gain access to sensitive resources or data by exploiting security weaknesses.
- Insufficient authorization checks: When authorization checks are insufficient, it can allow unauthorized users to access sensitive data or resources, or to perform actions that they are not authorized to do.
- Overly permissive access: When access controls are overly permissive, they can allow users to access resources or data that they do not need, increasing the risk of data breaches or other security incidents.
Check out these videos for a high-level explanation:
Missing function level access control
Missing object level access control
What is the impact of improper access control?
Improper access control can lead to various security threats, such as:
- Data breaches: Improper access control can allow attackers to access sensitive data, leading to data breaches, data loss, or unauthorized access to confidential information.
- Unauthorized access to resources: Attackers can exploit improper access control to gain unauthorized access to resources, such as servers, databases, and applications.
- Account takeover: Attackers can use improper access control to take over user accounts and gain access to sensitive data or resources.
How to prevent improper access control?
Here are some measures that can help ensure proper access control:
- Strong access controls: Implement strong access controls that restrict access to sensitive resources or data based on user roles and permissions.
- Proper user authentication and authorization: Implement proper user authentication and authorization mechanisms to ensure that only authorized users can access sensitive data and resources.
- Input validation and sanitization: Validate and sanitize user input before using it to access internal objects or data. Use regular expressions or input filters to remove or encode any special characters that could be used to access sensitive data or resources.
- Least privilege: Use the principle of least privilege to restrict access to resources to only what is necessary for each user role. This can help prevent attackers from gaining access to resources that they do not need to access.
- Regular security audits: Regularly audit your system for security vulnerabilities, including improper access control vulnerabilities. Use automated tools and manual testing to identify potential issues and fix them before they can be exploited.
References
Taxonomies
- OWASP Top 10 - A01 Broken Access Control
- CWE-284: Improper Access Control
- CWE-285: Improper Authorization
Explanation & Prevention
- OWASP: Broken Access Control
- OWASP: Authorization Testing
- OWASP: ASVS - V4 Access Control
- OWASP: Proactive Controls - C7 Enforce Access Controls
- OWASP: Authorization Cheat Sheet
Related CVEs
Training
Default Security Groups With Unrestricted Traffic
Check if the default security group does not restrict all inbound and outbound traffic. Security Groups set as default must be denied traffic.
Rule-specific references:
Option A: Make sure default Security Groups do not contain any rules
Both SecurityGroupIngress
and SecurityGroupEgress
Security groups with a GroupName
of "default" must not contain any rules.
- If a "default" Security Group does container rules and you need those rules, instead create the rules on a non-default Security Group and remove the rules from the "default" Security Group
- Test it
- Ship it 🚢 and relax 🌴
EC2 Instance Using Default Security Group
EC2 instances should not use default security group(s) (Security Group(s) with a name of "default").
Rule-specific references:
Option A: Remove any Default Security Groups
- Remove any default security groups from the configuration
- Add non-default security groups if needed
- Test it
- Ship it 🚢 and relax 🌴
ELB Sensitive Port Is Exposed To Entire Network
The AWS load balancer of the application with a sensitive port connection is exposed to the entire internet.
Rule-specific references:
Option A: Either remove sensitive ports or limit the number of source IP addresses able to traverse a given Security Group Ingress
Make sure that if sensitive ports are open in Properties.SecurityGroupIngress
then they should not be open to the entire network (Properties.SecurityGroupIngress.CidrIp
ends with /0).
If you locate the following bad patterns:
AWSTemplateFormatVersion: 2010-09-09
Resources:
MyLoadBalancer:
Type: AWS::ElasticLoadBalancing::LoadBalancer
Properties:
AvailabilityZones:
- "us-east-2a"
CrossZone: true
Scheme: internet-facing
Listeners:
- InstancePort: '80'
InstanceProtocol: HTTP
LoadBalancerPort: '443'
Protocol: HTTPS
PolicyNames:
- My-SSLNegotiation-Policy
SSLCertificateId: arn:aws:iam::123456789012:server-certificate/my-server-certificate
HealthCheck:
Target: HTTP:80/
HealthyThreshold: '2'
UnhealthyThreshold: '3'
Interval: '10'
Timeout: '5'
SecurityGroups:
- !Ref LBSecGroup
Policies:
- PolicyName: My-SSLNegotiation-Policy
PolicyType: SSLNegotiationPolicyType
Attributes:
- Name: Reference-Security-Policy
Value: ELBSecurityPolicy-TLS-1-2-2017-01
LBSecGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH
VpcId: my-vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 50
ToPort: 80
CidrIp: 127.0.0.1/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 127.0.0.1/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0Replace it with something similar to the following:
AWSTemplateFormatVersion: 2010-09-09
Resources:
MyLoadBalancer:
Type: AWS::ElasticLoadBalancing::LoadBalancer
Properties:
AvailabilityZones:
- "us-east-2a"
CrossZone: true
Scheme: internet-facing
Listeners:
- InstancePort: '80'
InstanceProtocol: HTTP
LoadBalancerPort: '443'
Protocol: HTTPS
PolicyNames:
- My-SSLNegotiation-Policy
SSLCertificateId: arn:aws:iam::123456789012:server-certificate/my-server-certificate
HealthCheck:
Target: HTTP:80/
HealthyThreshold: '2'
UnhealthyThreshold: '3'
Interval: '10'
Timeout: '5'
SecurityGroups:
[ !Ref LBNegativeSecGroup01 ]
Policies:
- PolicyName: My-SSLNegotiation-Policy
PolicyType: SSLNegotiationPolicyType
Attributes:
- Name: Reference-Security-Policy
Value: ELBSecurityPolicy-TLS-1-2-2017-01
LBNegativeSecGroup01:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH
VpcId: my-vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 50
ToPort: 80
CidrIp: 127.0.0.1/32
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 127.0.0.1/32
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0If you locate the following bad patterns:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
MySubnets:
Description: "My subnet"
Type: List<String>
Resources:
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: ip-target-alb
Subnets: !Ref MySubnets
SecurityGroups:
- !Ref ALBSecGroup
Tags:
- Key: Name
Value: ip-target-alb
ALBSecGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH
VpcId: my-vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 127.0.0.1/32
- IpProtocol: tcp
FromPort: 6379
ToPort: 6379
CidrIp: 127.0.0.1/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
HTTPALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
TargetGroupArn: !Ref IPTargetGroup
IPTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
VpcId: my-vpc
Port: 80
Protocol: HTTP
TargetType: ip
Matcher:
HttpCode: '200'
HealthCheckIntervalSeconds: 10
HealthCheckPath: /health/check
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 2
TestListenerRule1:
Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
Properties:
Priority: 1
ListenerArn: !Ref HTTPALBListener
Conditions:
- Field: "host-header"
Values:
- "test1.checkmarx.com"
Actions:
- Type: "forward"
TargetGroupArn: !Ref IPTargetGroup
Order: 1
ForwardConfig:
TargetGroups:
- TargetGroupArn: !Ref IPTargetGroup
Weight: 1
TargetGroupStickinessConfig:
Enabled: falseReplace it with something similar to the following:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
MySubnets:
Description: "My subnet"
Type: List<String>
Resources:
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: ip-target-alb
Subnets: !Ref MySubnets
SecurityGroups:
- !Ref ALBNegativeSecGroup
Tags:
- Key: Name
Value: ip-target-alb
ALBNegativeSecGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH
VpcId: my-vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 127.0.0.1/32
- IpProtocol: tcp
FromPort: 77
ToPort: 77
CidrIp: 127.0.0.1/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
HTTPALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
TargetGroupArn: !Ref IPTargetGroup
IPTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
VpcId: my-vpc
Port: 80
Protocol: HTTP
TargetType: ip
Matcher:
HttpCode: '200'
HealthCheckIntervalSeconds: 10
HealthCheckPath: /health/check
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 2
TestListenerRule1:
Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
Properties:
Priority: 1
ListenerArn: !Ref HTTPALBListener
Conditions:
- Field: "host-header"
Values:
- "test1.checkmarx.com"
Actions:
- Type: "forward"
TargetGroupArn: !Ref IPTargetGroup
Order: 1
ForwardConfig:
TargetGroups:
- TargetGroupArn: !Ref IPTargetGroup
Weight: 1
TargetGroupStickinessConfig:
Enabled: falseIf you locate the following bad patterns:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
MySubnet:
Description: "My subnet"
Type: List<String>
Resources:
GatewayLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: my-gateway-load-balancer
Scheme: internet-facing
Subnets: !Ref MySubnet
InstancesSecGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH
VpcId: my-vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 127.0.0.1/32
- IpProtocol: tcp
FromPort: 636
ToPort: 636
CidrIp: 127.0.0.1/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
EC2Instance01:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.2xlarge
SecurityGroups:
- !Ref 'InstancesSecGroup'
KeyName: my-rsa-key
ImageId: ami-79fd7eee
EC2Instance02:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.2xlarge
SecurityGroups:
- !Ref 'InstancesSecGroup'
KeyName: my-rsa-key
ImageId: ami-79fd7eee
GatewayLoadBalancerTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: t10-networklb-target
Port: 443
Protocol: TCP
VpcId: t10-vpc-id
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60
Targets:
- Id: !Ref EC2Instance01
Port: 443
- Id: !Ref EC2Instance02
Port: 443
Tags:
- Key: Name
Value: t10-networklb-target
GatewayLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref GatewayLoadBalancerTargetGroup
LoadBalancerArn: !Ref GatewayLoadBalancer
Port: 443
Protocol: TCP
GatewayLoadBalancerListenerCert:
Type: AWS::ElasticLoadBalancingV2::ListenerCertificate
Properties:
Certificates:
- CertificateArn: arn:aws:acm:eu-west-1:xxxaccountxxx:certificate/123456....
ListenerArn: !Ref GatewayLoadBalancerListenerReplace it with something similar to the following:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
MySubnet:
Description: "My subnet"
Type: List<String>
Resources:
NetworkLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: t10-networkloadbalancer
Scheme: internet-facing
Subnets: !Ref MySubnet
Type: network
Tags:
- Key: Name
Value: t10-networklb
InstancesNegativeSecGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH
VpcId: my-vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 127.0.0.1/32
- IpProtocol: tcp
FromPort: 77
ToPort: 77
CidrIp: 127.0.0.1/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
EC2Instance01:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.2xlarge
SecurityGroups: [!Ref 'InstancesNegativeSecGroup']
KeyName: my-rsa-key
ImageId: ami-79fd7eee
EC2Instance02:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.2xlarge
SecurityGroups: [!Ref 'InstancesNegativeSecGroup']
KeyName: my-rsa-key
ImageId: ami-79fd7eee
NetworkLoadBalancerTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: t10-networklb-target
Port: 443
Protocol: TCP
VpcId: t10-vpc-id
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60
Targets:
- Id: !Ref EC2Instance01
Port: 443
- Id: !Ref EC2Instance02
Port: 443
Tags:
- Key: Name
Value: t10-networklb-target
NetworkLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref NetworkLoadBalancerTargetGroup
LoadBalancerArn: !Ref NetworkLoadBalancer
Port: 443
Protocol: TCP
NetworkLoadBalancerListenerCert:
Type: AWS::ElasticLoadBalancingV2::ListenerCertificate
Properties:
Certificates:
- CertificateArn: arn:aws:acm:eu-west-1:xxxaccountxxx:certificate/123456....
ListenerArn: !Ref NetworkLoadBalancerListenerTest it
Ship it 🚢 and relax 🌴
IAM Policies With Full Privileges
IAM policies should not allow full administrative privileges (for all resources).
Rule-specific references:
Option A: Remove the All Specifier from the Resource and Action Statements of the Policy
Policies should not contain Statement
s with Action
s and Resource
s that Allow
all ("*").
- Remove the value "*" from any
Action
andResource
and replace it with only the number of actions and resources needed - Test it
- Ship it 🚢 and relax 🌴
IAM Policy Grants AssumeRole
Permission Across All Services
Check if any IAM Policy grants AssumeRole
permission across all services.
Rule-specific references:
Option A: Replace the Resource's All Specifier with a more focussed Resource and Replace the Action with more specific Action(s)
A policy (AWS::IAM::Policy
) should not have a Statement
with Effect
: "Allow" and an Action
of "sts:AssumeRole" with a Resource
property that specifies all ("*"). Similar to the following example:
{
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "mygrouppolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": "*"
}
]
},
...
}
}
Remove the value "*" from the
Resource
or replace it with as few services as possible (ideally one)Replace "sts:AssumeRole" with discreet
Action
s{
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "mygrouppolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::myAWSBucket/*"
}
]
},
...
}
}Test it
Ship it 🚢 and relax 🌴
IAM Policy Grants Full Permissions
Check if an IAM policy is granting full permissions to resources from the get-go, instead of granting permissions gradually as necessary.
Rule-specific references:
Option A: Remove the All Specifier from the Action and make sure the Resource does not allow All or Admin
A policy (AWS::IAM::Policy
) should not have a Statement
with Effect
: "Allow" and an Action
of all ("*") with a Resource
property that specifies all ("*") or "arn:aws:iam::aws:policy/AdministratorAccess".
- Remove the value "*" from any
Action
that has a siblingResource
property that specifies all ("*") or "arn:aws:iam::aws:policy/AdministratorAccess" - Test it
- Ship it 🚢 and relax 🌴
S3 Bucket ACL Allows Read Or Write to All Users
S3 Buckets should not be readable and writable to all users.
Rule-specific references:
Option A: An S3 Bucket Should Not Have Access Control of Public Read Write
A bucket (AWS::S3::Bucket
) should not have an AccessControl
of "PublicReadWrite"
- Replace any S3 Bucket
AccessControl
values of "PublicReadWrite" with a more restrictive value - Test it
- Ship it 🚢 and relax 🌴
S3 Bucket ACL Allows Read to Any Authenticated User
S3 Buckets should not be readable to all authenticated users.
Rule-specific references:
Option A: An S3 Bucket Should Not Have an Access Control of Authenticated Read.
A bucket (AWS::S3::Bucket
) should not have an AccessControl
of AuthenticatedRead
- Remove or replace the value "AuthenticatedRead" from any S3 Bucket
AccessControl
with a more restrictive value - Test it
- Ship it 🚢 and relax 🌴
Rule-specific references:
S3 Bucket Access to Any Principal
The S3 Bucket should not have the (PublicAccessBlockConfiguration
empty or PublicAccessBlockConfiguration.IgnorePublicAcls
= false or PublicAccessBlockConfiguration.RestrictPublicBuckets
= false ) and ( policy.Statement
contain [Effect
="Allow" and (Principal
="*" or Principal.AWS
="*")]).
Option A: Reconfigure the S3 Bucket
Consider changing the defective configuration with the more secure configuration as outlined in the examples below:
Defective:
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: false
BlockPublicPolicy: false
IgnorePublicAcls: true
RestrictPublicBuckets: false
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref Bucket
PolicyDocument:
Statement:
- Effect: Allow
Principal:
AWS:
- "*"
Action: s3:GetObject
Resource: arn:aws:s3:::DOC-EXAMPLE-BUCKET/*
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'
Bucket2:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: false
BlockPublicPolicy: false
IgnorePublicAcls: false
RestrictPublicBuckets: true
BucketPolicy2:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref Bucket2
PolicyDocument:
Statement:
- Effect: Allow
Principal:
AWS:
- "*"
Action: s3:GetObject
Resource: arn:aws:s3:::DOC-EXAMPLE-BUCKET/*
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Not Defective:
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: false
BlockPublicPolicy: false
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref Bucket
PolicyDocument:
Statement:
- Effect: Allow
Principal:
AWS:
- arn:aws:iam::111122223333:user/Alice
- arn:aws:iam::111122223333:user/Fabio
Action: s3:GetObject
Resource: arn:aws:s3:::DOC-EXAMPLE-BUCKET/*
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Test it
Ship it 🚢 and relax 🌴
S3 Bucket Allows Put Action From All Principals
S3 Buckets must not allow Put Actions From All Principals, as to prevent leaking private information to the entire internet or allow unauthorized data tampering/deletion. This means the 'Effect' must not be 'Allow' when the 'Action' is Put, for all Principals.
Rule-specific references:
Option A: Constrain Resource and/or Principal values to something more granular
Where a Put action is present the Resource and/or Principal should not be All ("*").
Locate the following pattern:
Resources:
SampleBucketPolicy1:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:PutObject"
- "s3:GetObject"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Change the value of the
Resource
and/orPrincipal
to more granular valuesTest it
Ship it 🚢 and relax 🌴
Option B: Set Effect to Deny where a Principal specifies All
Where a Principal specifies All ("*"), the Effect should be to Deny.
Locate the following pattern:
Resources:
SampleBucketPolicy3:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:PutObject"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'And modify it to:
Resources:
SampleBucketPolicy4:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:PutObject"
Effect: Deny
Resource: '*'
Principal: '*'
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Test it
Ship it 🚢 and relax 🌴
S3 Bucket Allows Delete Action From All Principals
S3 Buckets must not allow Delete Actions From All Principals, as to prevent leaking private information to the entire internet or allow unauthorized data tampering/deletion. This means the 'Effect' must not be 'Allow' when the 'Action' is Delete, for all Principals.
Rule-specific references:
Option A: Constrain Resource and/or Principal values to something more granular
Where a Delete action is present the Resource and/or Principal should not be All ("*").
Locate the following pattern:
Resources:
SampleBucketPolicy1:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:DeleteObject"
- "s3:GetObject"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Change the value of the
Resource
and/orPrincipal
to more granular valuesTest it
Ship it 🚢 and relax 🌴
Option B: Set Effect to Deny where a Principal specifies All
Where a Principal specifies All ("*"), the Effect should be to Deny.
Locate the following pattern:
Resources:
SampleBucketPolicy3:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:DeleteObject"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'And modify it to:
Resources:
SampleBucketPolicy4:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:DeleteObject"
Effect: Deny
Resource: '*'
Principal: '*'
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Test it
Ship it 🚢 and relax 🌴
S3 Bucket Allows Get Action From All Principals
S3 Buckets must not allow Get Actions From All Principals, as to prevent leaking private information to the entire internet or allow unauthorized data tampering/deletion. This means the 'Effect' must not be 'Allow' when the 'Action' is Get, for all Principals.
Rule-specific references:
Option A: Constrain Resource and/or Principal values to something more granular
Where a Get action is present the Resource and/or Principal should not be All ("*").
Locate the following pattern:
Resources:
SampleBucketPolicy1:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:DeleteObject"
- "s3:GetObject"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Change the value of the
Resource
and/orPrincipal
to more granular valuesTest it
Ship it 🚢 and relax 🌴
Option B: Set Effect to Deny where a Principal specifies All
Where a Principal specifies All ("*"), the Effect should be to Deny.
Locate the following pattern:
Resources:
SampleBucketPolicy3:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:GetObject"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'And modify it to:
Resources:
SampleBucketPolicy4:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:GetObject"
Effect: Deny
Resource: '*'
Principal: '*'
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Test it
Ship it 🚢 and relax 🌴
S3 Bucket Allows List Action From All Principals
S3 Buckets must not allow List Actions From All Principals, as to prevent leaking private information to the entire internet or allow unauthorized data tampering/deletion. This means the 'Effect' must not be 'Allow' when the 'Action' is 'List', for all Principals.
Rule-specific references:
Option A: Constrain Resource and/or Principal values to something more granular
Where a List action is present the Resource and/or Principal should not be All ("*").
Locate the following pattern:
Resources:
SampleBucketPolicy1:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:ListObject"
- "s3:GetObject"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Change the value of the
Resource
and/orPrincipal
to more granular valuesTest it
Ship it 🚢 and relax 🌴
Option B: Set Effect to Deny where a Principal specifies All
Where a Principal specifies All ("*"), the Effect should be to Deny.
Locate the following pattern:
Resources:
SampleBucketPolicy3:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:ListObject"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'And modify it to:
Resources:
SampleBucketPolicy4:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:ListObject"
Effect: Deny
Resource: '*'
Principal: '*'
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Test it
Ship it 🚢 and relax 🌴
S3 Bucket With All Permissions
S3 Buckets must not have all permissions, as to prevent leaking private information to the entire internet or allow unauthorized data tampering/deletion. This means the 'Effect' must not be 'Allow' when the 'Action' is '*', for all Principals.
Rule-specific references:
Option A: Constrain Resource and/or Principal values to something more granular
Where all ("*") Action
s are allowed the Resource
and Principal
should not be All ("*").
Locate the following pattern:
Resources:
SampleBucketPolicy1:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action: "*"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Change the value of the
Resource
andPrincipal
to more granular valuesTest it
Ship it 🚢 and relax 🌴
Option B: Set Effect to Deny where a Principal specifies All
Where a Principle specifies All ("*"), the Effect should be to Deny.
Locate the following pattern:
Resources:
SampleBucketPolicy3:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action: "*"
Effect: Allow
Resource: "*"
Principal: "*"
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'And modify it to:
Resources:
SampleBucketPolicy4:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref DOC-EXAMPLE-BUCKET
PolicyDocument:
Statement:
- Action:
- "s3:ListObject"
Effect: Deny
Resource: '*'
Principal: '*'
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'Test it
Ship it 🚢 and relax 🌴
Security Group With Unrestricted Access To SSH
SSH (TCP:22) should not be exposed to the world in AWS Security Group. There is very rarely a need for ranges of IP addresses to be able to access SSH port 22.
Rule-specific references:
Option A: Only specify single IP addresses or a very small range that can access SSH port 22
All SecurityGroupIngress
blocks of any given AWS::EC2::SecurityGroup
should not have port 22 open to the world.
Locate one of the following vulnerable patterns:
Resources:
Ec2Instance:
Type: 'AWS::EC2::Instance'
Properties:
SecurityGroups:
- !Ref InstanceSecurityGroup
KeyName: mykey
ImageId: ''
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0Modify the config to something like the following:
Resources:
Ec2Instance:
Type: 'AWS::EC2::Instance'
Properties:
SecurityGroups:
- !Ref InstanceSecurityGroup
KeyName: mykey
ImageId: ''
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 203.0.113.1/32Test it
Ship it 🚢 and relax 🌴
Security Group Ingress With All Protocols
AWS Security Group Ingress should not specify all protocols to prevent allowing traffic on all ports.
Rule-specific references:
Option A: Set the value of the IP Protocol to a single specific protocol
Change all occurrences of SecurityGroupIngress
[n].IpProtocol
and Properties.IpProtocol
with value -1 to one of the accepted specific protocols.
Locate the following pattern:
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: -1
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
OutboundRule:
Type: AWS::EC2::SecurityGroupEgress
Properties:
IpProtocol: tcp
FromPort: 0
ToPort: 65535
DestinationSecurityGroupId:
Fn::GetAtt:
- TargetSG
- GroupId
GroupId:
Fn::GetAtt:
- SourceSG
- GroupId
InboundRule:
Type: AWS::EC2::SecurityGroupIngress
Properties:
IpProtocol: -1
FromPort: 0
ToPort: 65535
SourceSecurityGroupId:
Fn::GetAtt:
- SourceSG
- GroupId
GroupId:
Fn::GetAtt:
- TargetSG
- GroupIdModify it to something like the following:
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
OutboundRule:
Type: AWS::EC2::SecurityGroupEgress
Properties:
IpProtocol: tcp
FromPort: 0
ToPort: 65535
DestinationSecurityGroupId:
Fn::GetAtt:
- TargetSG
- GroupId
GroupId:
Fn::GetAtt:
- SourceSG
- GroupId
InboundRule:
Type: AWS::EC2::SecurityGroupIngress
Properties:
IpProtocol: tcp
FromPort: 0
ToPort: 65535
SourceSecurityGroupId:
Fn::GetAtt:
- SourceSG
- GroupId
GroupId:
Fn::GetAtt:
- TargetSG
- GroupIdTest it
Ship it 🚢 and relax 🌴
Security Group Unrestricted Access To RDP
AWS EC2 Security Groups should not allow 0.0.0.0/0 for RDP (port:3389).
Rule-specific references:
Option A: Do not allow RDP ports to be open in a Security Group
Spoofing IP addresses is a possible attack, and RDP has had many known vulnerabilities, so just restricting the number of IP addresses that can access the RDP ports is probably not your best option. By far the best option is to not allow RDP ports to be open. If you must use RDP use it inside a VPN or SSH tunnel. Also, by restricting the number of IP addresses that are allowed access to any given port you are helping to restrict any blast radius.
Locate the following pattern:
Resources:
Ec2Instance:
Type: 'AWS::EC2::Instance'
Properties:
SecurityGroups:
- !Ref InstanceSecurityGroup
KeyName: mykey
ImageId: ''
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3389
ToPort: 3389
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0Modify it to something like the following:
Resources:
Ec2Instance:
Type: 'AWS::EC2::Instance'
Properties:
SecurityGroups:
- !Ref InstanceSecurityGroup
KeyName: mykey
ImageId: ''
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 127.0.0.1/32
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 127.0.0.1/33Test it
Ship it 🚢 and relax 🌴
Security Groups Allows Unrestricted Outbound Traffic
No security group should allow unrestricted egress access.
Rule-specific references:
Option A: Set the value of the IP Protocol to a single specific protocol
Change all occurrences of Properties.SecurityGroupEgress
[n].IpProtocol
with value "ALL" to one of the accepted specific protocols.
Locate the following pattern:
Parameters:
KeyName:
Description: The EC2 Key Pair to allow SSH access to the instance
Type: 'AWS::EC2::KeyPair::KeyName'
Resources:
Ec2Instance:
Type: 'AWS::EC2::Instance'
Properties:
SecurityGroups:
- !Ref InstanceSecurityGroup
- MyExistingSecurityGroup
KeyName: !Ref KeyName
ImageId: ami-7a11e213
InstanceSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: ALL
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0Modify it to something like the following:
Parameters:
KeyName:
Description: The EC2 Key Pair to allow SSH access to the instance
Type: 'AWS::EC2::KeyPair::KeyName'
Resources:
Ec2Instance:
Type: 'AWS::EC2::Instance'
Properties:
SecurityGroups:
- !Ref InstanceSecurityGroup
- MyExistingSecurityGroup
KeyName: !Ref KeyName
ImageId: ami-7a11e213
InstanceSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0Test it
Ship it 🚢 and relax 🌴
Unrestricted Security Group Ingress
AWS Security Group Ingress CIDR should ideally not be open to the world.
Rule-specific references:
Option A: Limit the Source IP addresses that can access VPC targets
Ideally, limit the number of Source IP addresses that can send data that is allowed through a given port.
Locate the following pattern:
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
Description: TCP
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
Description: TCP
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
OutboundRule:
Type: AWS::EC2::SecurityGroupEgress
Properties:
Description: TCP
IpProtocol: tcp
FromPort: 0
ToPort: 65535
CidrIp: 0.0.0.0/0
DestinationSecurityGroupId:
Fn::GetAtt:
- TargetSG
- GroupId
GroupId:
Fn::GetAtt:
- SourceSG
- GroupId
InboundRule:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: TCP
IpProtocol: tcp
FromPort: 0
ToPort: 65535
CidrIpv6: ::/0
SourceSecurityGroupId:
Fn::GetAtt:
- SourceSG
- GroupId
GroupId:
Fn::GetAtt:
- TargetSG
- GroupIdModify it to something like the following:
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
Description: TCP
FromPort: 80
ToPort: 80
CidrIp: 192.0.2.0/24
SecurityGroupEgress:
- IpProtocol: tcp
Description: TCP
FromPort: 80
ToPort: 80
CidrIp: 192.0.2.0/24
OutboundRule:
Type: AWS::EC2::SecurityGroupEgress
Properties:
Description: TCP
IpProtocol: tcp
FromPort: 0
ToPort: 0
CidrIp: 192.0.2.0/24
DestinationSecurityGroupId:
Fn::GetAtt:
- TargetSG
- GroupId
GroupId:
Fn::GetAtt:
- SourceSG
- GroupId
InboundRule:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: TCP
IpProtocol: tcp
FromPort: 0
ToPort: 0
CidrIpv6: 2001:0DB8:1234::/48
SourceSecurityGroupId:
Fn::GetAtt:
- SourceSG
- GroupId
GroupId:
Fn::GetAtt:
- TargetSG
- GroupIdTest it
Ship it 🚢 and relax 🌴
EC2 Sensitive Port Is Publicly Exposed
The AWS EC2 instance has a sensitive port connection exposed to the entire network.
Rule-specific references:
Option A: Limit the number of source IP addresses able to traverse inbound ports
CidrIp
should not end with \0 (allowing all sources). Instead limit the CidrIp
to as few source IP addresses as possible, ideally with a trailing \32.
Ideally, the IpProtocol
should not be -1 (all) but be something more specific.
Locate the following bad patterns:
Pattern one:
AWSTemplateFormatVersion: 2010-09-09T00:00:00Z
Resources:
UnsafeSecGroup01:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and redis
VpcId: my-vpc
SecurityGroupIngress:
- FromPort: 8080
ToPort: 8080
CidrIp: 127.0.0.1/32
IpProtocol: tcp
- IpProtocol: tcp
FromPort: 6379
ToPort: 6379
CidrIp: 10.0.0.1/0
SecurityGroupEgress:
- FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
IpProtocol: tcp
EC2Instance01:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-79fd7eee
InstanceType: t3.medium
SecurityGroups:
- UnsafeSecGroup01
KeyName: my-new-rsa-keyPattern two:
AWSTemplateFormatVersion: 2010-09-09T00:00:00Z
Resources:
UnsafeSecGroup02:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and mysql
VpcId: my-vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 127.0.0.1/32
- ToPort: 1434
CidrIp: 10.0.0.1/0
IpProtocol: tcp
FromPort: 1433
- IpProtocol: tcp
FromPort: 150
ToPort: 180
CidrIp: 10.0.0.1/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
EC2Instance02:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.medium
SecurityGroups:
- UnsafeSecGroup02
KeyName: my-new-rsa-key
ImageId: ami-79fd7eeePattern three:
AWSTemplateFormatVersion: 2010-09-09T00:00:00Z
Resources:
UnsafeSecGroup03:
Type: AWS::EC2::SecurityGroup
Properties:
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
GroupDescription: Allow HTTP and hadoop
VpcId: my-vpc
SecurityGroupIngress:
- ToPort: 80
CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 80
- ToPort: 9000
CidrIp: 10.0.0.1/0
IpProtocol: tcp
FromPort: 9000
EC2Instance03:
Type: AWS::EC2::Instance
Properties:
SecurityGroups:
- UnsafeSecGroup03
KeyName: my-new-rsa-key
ImageId: ami-79fd7eee
InstanceType: t3.mediumPattern four:
AWSTemplateFormatVersion: 2010-09-09T00:00:00Z
Resources:
UnsafeSecGroup04:
Type: AWS::EC2::SecurityGroup
Properties:
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
GroupDescription: Allow LDAP and SNMP
VpcId: my-vpc
SecurityGroupIngress:
- ToPort: 389
FromPort: 389
IpProtocol: all
CidrIp: 10.0.0.0/0
- ToPort: 150
FromPort: 180
IpProtocol: udp
CidrIp: 10.0.0.1/0
- ToPort: 53
FromPort: 53
IpProtocol: "-1"
CidrIp: 10.0.0.1/0
EC2Instance03:
Type: AWS::EC2::Instance
Properties:
SecurityGroups:
- UnsafeSecGroup04
KeyName: my-new-rsa-key
ImageId: ami-79fd7eee
InstanceType: t3.mediumModify the Security Group(s) to something like the following:
AWSTemplateFormatVersion: 2010-09-09T00:00:00Z
Resources:
SafeSecGroup:
Type: AWS::EC2::SecurityGroup
Properties:
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 127.0.0.1/32
GroupDescription: Allow HTTP and SSH
VpcId: my-vpc
SecurityGroupIngress:
- FromPort: 80
ToPort: 80
CidrIp: 127.0.0.1/32
IpProtocol: tcp
- ToPort: 77
CidrIp: 127.0.0.1/32
IpProtocol: all
FromPort: 77
MyNegativeEC2Instance:
Type: AWS::EC2::Instance
Properties:
SecurityGroups:
- SafeSecGroup
KeyName: my-new-rsa-key
ImageId: ami-79fd7eee
InstanceType: t3.mediumTest it
Ship it 🚢 and relax 🌴
Remote Desktop Port Open
The Remote Desktop port (3389) is open to the world in an AWS EC2 Security Group. If you need to provide Remote Desktop communications to an EC2 instance, do so via a VPN or SSH tunnel.
Rule-specific references:
Option A: Close the Remote Desktop ingress port (3389)
The recommended option is to remove the RDP port and use either a VPN or SSH tunnel in which any RDP traffic or other traffic can pass encrypted.
Locate the following pattern:
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow rdp to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3389
ToPort: 3389
CidrIp: 0.0.0.0/0Modify the config to something like the following:
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow rdp to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 203.0.113.1/32Test it
Ship it 🚢 and relax 🌴
Option B: Limit the Remote Desktop ingress port (3389) to a single or very small set of IP addresses
Although this option satisfies the security rule, it's still not a great option. RDP has a long history of vulnerabilities and is usually best to be encrypted inside a VPN or SSH tunnel. However: If you still want to pass RDP traffic over a network then follow these steps:
Locate the following pattern:
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow rdp to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3389
ToPort: 3389
CidrIp: 0.0.0.0/0Modify the config to something like the following:
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow rdp to client host
VpcId:
Ref: myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3389
ToPort: 3389
CidrIp: 203.0.113.1/32Test it
Ship it 🚢 and relax 🌴