Skip to main content
MEDIUMEC2Security

VPC Default Security Group Has Rules

vpc-default-security-group-rules-present

What this rule checks

Detects standalone security group rules attached to a VPC default security group (GroupId referencing Fn::GetAtt DefaultSecurityGroup). CIS requires the default group to have no rules.

How to fix it

  1. 1Attach rules to a purpose-built security group instead of the VPC default group
  2. 2In CDK, enable restrictDefaultSecurityGroup: true on the Vpc so the default group has no rules
FlaggedThe rule follows Fn::GetAtt DefaultSecurityGroup and flags the standalone ingress attached to the VPC's actual default security group. Default groups cannot be deleted and should be left empty.
import { App, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

const vpc = new ec2.CfnVPC(this, 'Vpc', { cidrBlock: '10.0.0.0/16' });
// FLAGGED: a standalone ingress rule targets the VPC's real default SG.
new ec2.CfnSecurityGroupIngress(this, 'DefaultSgIngress', {
  groupId: vpc.attrDefaultSecurityGroup,
  ipProtocol: 'tcp',
  fromPort: 443,
  toPort: 443,
  cidrIp: '0.0.0.0/0',
});
FixedThe default group is left with no rules, and traffic is governed by a dedicated security group. The rule only flags standalone rules that reference a VPC's DefaultSecurityGroup attribute.
import { App, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

const vpc = new ec2.CfnVPC(this, 'Vpc', { cidrBlock: '10.0.0.0/16' });
// FIXED: the default group stays untouched; a purpose-built SG carries rules.
const webSg = new ec2.CfnSecurityGroup(this, 'WebSg', {
  vpcId: vpc.ref,
  groupDescription: 'web tier',
});
new ec2.CfnSecurityGroupIngress(this, 'WebIngress', {
  groupId: webSg.attrGroupId,
  ipProtocol: 'tcp',
  fromPort: 443,
  toPort: 443,
  cidrIp: '0.0.0.0/0',
});

CDK Insights pinpoints the exact file and line in your CDK source for every finding, so you can jump straight to the fix.

Affected resource types

AWS::EC2::SecurityGroupIngressAWS::EC2::SecurityGroupEgress

Compliance frameworks

SOC2HIPAAPCI-DSSCISNIST

AWS documentation

Read the AWS guidance

Intentional? Suppress this finding

Sometimes a flag is deliberate - a genuinely public endpoint, say. You can dismiss vpc-default-security-group-rules-present and the reason is kept in the report, not silently hidden.

In .cdk-insights.json:

{
  "ignoreRules": [
    { "id": "vpc-default-security-group-rules-present", "reason": "Why this is intentional" }
  ]
}

Or inline in your CDK code:

Validations.of(scope).acknowledge({
  id: 'cdk-insights::vpc-default-security-group-rules-present',
  reason: 'Why this is intentional',
});

Use the rule ID vpc-default-security-group-rules-present shown above - not the CDK-* ID from SARIF / GitHub code scanning. To dismiss every finding on one construct instead, use ignorePaths. Suppression docs →

Catch this in your stack

$ npx cdk-insights scan

CDK Insights runs this and 144+ other rules locally against your synthesised CDK app - free, no account, your code never leaves your machine.

More EC2 rules