Security group permits a broad source range

Limit security group ingress to clients that actually need to connect.

Description

A broad CIDR range in a security group can include systems that do not need access to the service or database. Restrict sources to business requirements on internal networks as well as public ones.

A prefix length alone cannot establish an appropriate access boundary. Review actual clients, protocols, ports and connectivity together. Network access does not replace database authentication or permissions.

Potential impact

  • More reachable systems can increase unwanted connection attempts and opportunities to exploit a vulnerable service.
  • A compromised system within an allowed range can provide a path for further internal access attempts.

Remediation

  • Narrow EC2 CidrIp and CidrIpv6 rules to required addresses, ports and protocols. Where supported, consider referencing the application’s security group.
  • Assess legacy RDS DB security group CIDRIP rules against actual clients too. Use VPC security groups for RDS in a current VPC.
  • Identify required connections before the change, then test that approved clients can connect and other connections are blocked.

Examples

These MySQL examples use a VPC security group. Supply a DB subnet group in the same VPC, a supported DB instance class and an administrator name. RDS manages the password in Secrets Manager. Replace the example addresses with actual approved client addresses.

Before

yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
  DBSubnetGroupName:
    Type: String
  DBInstanceClass:
    Type: String
  MasterUsername:
    Type: String
Resources:
  DBinstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      VPCSecurityGroups:
        - Ref: DbSecurity
      AllocatedStorage: "20"
      DBInstanceClass: !Ref DBInstanceClass
      DBSubnetGroupName: !Ref DBSubnetGroupName
      Engine: mysql
      MasterUsername: !Ref MasterUsername
      ManageMasterUserPassword: true
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
  DbSecurity:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: MySQL access
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 10.0.0.0/23

An internal /23 range can reach MySQL port 3306. Check whether every address in that range needs access.

After

yaml
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
  DBSubnetGroupName:
    Type: String
  DBInstanceClass:
    Type: String
  MasterUsername:
    Type: String
Resources:
  DBinstance1:
    Type: AWS::RDS::DBInstance
    Properties:
      VPCSecurityGroups:
        - Ref: DbSecurity
      AllocatedStorage: "20"
      DBInstanceClass: !Ref DBInstanceClass
      DBSubnetGroupName: !Ref DBSubnetGroupName
      Engine: mysql
      MasterUsername: !Ref MasterUsername
      ManageMasterUserPassword: true
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
  DbSecurity:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: MySQL access
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 10.0.1.10/32

The range is reduced to one IPv4 address. Verify that it belongs to the approved client and review additional permissions from other attached security groups.

References