Detection rules › Panther
AWS Security Group Restricts Traffic Leaving CDE
This policy validates that there are restrictions on what type of traffic may leave Security Groups that are considered with the scope of the PCI CDE. These restrictions help ensure that cardholder data does not leave the CDE.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Exfiltration | T1567 Exfiltration Over Web Service |
Rule body yaml
AnalysisType: policy
Filename: aws_security_group_restricts_traffic_leaving_cde.py
PolicyID: "AWS.SecurityGroup.RestrictsTrafficLeavingCDE"
DisplayName: "AWS Security Group Restricts Traffic Leaving CDE"
Enabled: false
ResourceTypes:
- AWS.EC2.SecurityGroup
Tags:
- AWS
- PCI
- Exfiltration:Exfiltration Over Web Service
Reports:
MITRE ATT&CK:
- TA0010:T1567
Severity: Medium
Description: >
This policy validates that there are restrictions on what type of traffic may leave Security Groups that are considered with the scope of the PCI CDE. These restrictions help ensure that cardholder data does not leave the CDE.
Runbook: >
Add appropriate restrictions to traffic leaving Security Groups considered a part of the CDE.
Reference: https://docs.aws.amazon.com/cli/latest/userguide/cli-services-ec2-sg.html
Tests:
- Name: Security Group Restricts Traffic Leaving CDE
ExpectedResult: true
Resource:
{
"Description": "example VPC security group",
"GroupId": "sg-abc123",
"GroupName": "default",
"IpPermissions":
[
{
"FromPort": null,
"IpProtocol": "-1",
"IpRanges": null,
"Ipv6Ranges": null,
"PrefixListIds": null,
"ToPort": null,
"UserIdGroupPairs":
[
{
"Description": null,
"GroupId": "sg-def123",
"GroupName": null,
"PeeringStatus": null,
"UserId": "123456789012",
"VpcId": null,
"VpcPeeringConnectionId": null,
},
],
},
],
"IpPermissionsEgress":
[
{
"FromPort": 22,
"IpProtocol": "-1",
"IpRanges": [{ "CidrIp": "10.0.10.0/24", "Description": null }],
"Ipv6Ranges": null,
"PrefixListIds": null,
"ToPort": 22,
"UserIdGroupPairs": null,
},
],
"OwnerId": "123456789012",
"Tags": { "environment": "pci" },
"VpcId": "vpc-abc111222333",
}
- Name: Security Group Does Not Restrict Traffic Leaving CDE
ExpectedResult: false
Resource:
{
"Description": "example VPC security group",
"GroupId": "sg-abc123",
"GroupName": "default",
"IpPermissions":
[
{
"FromPort": null,
"IpProtocol": "-1",
"IpRanges": null,
"Ipv6Ranges": null,
"PrefixListIds": null,
"ToPort": null,
"UserIdGroupPairs":
[
{
"Description": null,
"GroupId": "sg-def123",
"GroupName": null,
"PeeringStatus": null,
"UserId": "123456789012",
"VpcId": null,
"VpcPeeringConnectionId": null,
},
],
},
],
"IpPermissionsEgress":
[
{
"FromPort": null,
"IpProtocol": "-1",
"IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": null }],
"Ipv6Ranges": null,
"PrefixListIds": null,
"ToPort": null,
"UserIdGroupPairs": null,
},
],
"OwnerId": "123456789012",
"Tags": { "environment": "pci" },
"VpcId": "vpc-abc111222333",
}
Detection logic
Rule logic imperative Python
from ipaddress import ip_network
def policy(resource):
for permission in resource["IpPermissionsEgress"] or []:
for ip_range in permission["IpRanges"] or []:
if ip_range["CidrIp"] == "0.0.0.0/0" or not ip_network(ip_range["CidrIp"]).is_private:
return False
for ip_range in permission["Ipv6Ranges"] or []:
if ip_range["CidrIpv6"] == "::/0" or not ip_network(ip_range["CidrIpv6"]).is_private:
return False
return True
The parser cannot express this rule's logic as a field filter; the imperative Python above is the detection.