Skip to content

Commit 2356bd2

Browse files
authored
Merge pull request hashicorp#272 from ja5onhughe5/master
Null check, better violation msgs, and added function descriptions
2 parents f3e9cc4 + 183b4f9 commit 2356bd2

File tree

6 files changed

+298
-63
lines changed

6 files changed

+298
-63
lines changed

governance/third-generation/aws/restrict-ingress-sg-rule-rdp.sentinel

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This policy uses the Sentinel tfplan/v2 import to validate that no security group
2-
# rules have the have SSH open to CIDR "0.0.0.0/0" for ingress rules. It covers both the
2+
# rules have the have RDP open to CIDR "0.0.0.0/0" for ingress rules. It covers both the
33
# aws_security_group and the aws_security_group_rule resources which can both
44
# define rules.
55

@@ -40,19 +40,50 @@ for aws_security_group_rules as address, sgr {
4040
# We check that it is present and really a list
4141
# before checking whether it contains "0.0.0.0/0"
4242
if sgr.change.after.cidr_blocks else null is not null and
43+
types.type_of(sgr.change.after.cidr_blocks) is "list" and
44+
sgr.change.after.cidr_blocks contains "0.0.0.0/0" and
45+
sgr.change.after.from_port else null is null and
46+
sgr.change.after.to_port else null is not null and
47+
sgr.change.after.to_port is forbidden_to_port{
48+
violatingSGRulesCount += 1
49+
print("SG Rule Ingress Violation:", address, "has port", forbidden_port,
50+
"(RDP) open to", forbidden_cidrs, "that is not allowed")
51+
print(" Ingress Rule has from_port that is null or undefined")
52+
print(" and Ingress Rule has to_port with value", sgr.change.after.to_port)
53+
print(" The to_port and from_port both need to be set to an integer",
54+
"range or of equal")
55+
print(" value to each other that is either less than or greater than", forbidden_port)
56+
} else if sgr.change.after.cidr_blocks else null is not null and
4357
types.type_of(sgr.change.after.cidr_blocks) is "list" and
4458
sgr.change.after.cidr_blocks contains "0.0.0.0/0" and
4559
sgr.change.after.from_port else null is not null and
46-
sgr.change.after.from_port <= forbidden_from_port and
60+
sgr.change.after.from_port is forbidden_from_port and
61+
sgr.change.after.to_port else null is null{
62+
violatingSGRulesCount += 1
63+
print("SG Rule Ingress Violation:", address, "has port", forbidden_port,
64+
"(RDP) open to", forbidden_cidrs, "that is not allowed")
65+
print(" Ingress Rule has from_port with value", sgr.change.after.from_port)
66+
print(" and Ingress Rule has to_port that is null or undefined")
67+
print(" The to_port and from_port both need to be set to an integer",
68+
"range or of equal")
69+
print(" value to each other that is either less than or greater than", forbidden_port)
70+
} else if sgr.change.after.cidr_blocks else null is not null and
71+
types.type_of(sgr.change.after.cidr_blocks) is "list" and
72+
sgr.change.after.cidr_blocks contains "0.0.0.0/0" and
73+
sgr.change.after.from_port else null is not null and
74+
sgr.change.after.from_port <= forbidden_from_port and
4775
sgr.change.after.to_port else null is not null and
4876
sgr.change.after.to_port >= forbidden_to_port{
4977
violatingSGRulesCount += 1
5078
print("SG Rule Ingress Violation:", address, "has port", forbidden_port,
5179
"(RDP) open to", forbidden_cidrs, "that is not allowed")
52-
print(" Ingress Rule", "has from_port with value", sgr.change.after.from_port,
80+
print(" Ingress Rule has from_port with value", sgr.change.after.from_port,
5381
"that is less than or equal to", forbidden_from_port)
54-
print(" and Ingress Rule has to_port with value", sgr.change.after.to_port,
82+
print(" and Ingress Rule has to_port with value", sgr.change.after.to_port,
5583
"that is greater than or equal to", forbidden_to_port)
84+
print(" The to_port and from_port both need to be set to an integer",
85+
"range or of equal")
86+
print(" value to each other that is either less than or greater than", forbidden_port)
5687
} else if sgr.change.after.cidr_blocks else null is not null and
5788
types.type_of(sgr.change.after.cidr_blocks) is "list" and
5889
sgr.change.after.cidr_blocks contains "0.0.0.0/0" and
@@ -61,7 +92,10 @@ for aws_security_group_rules as address, sgr {
6192
violatingSGRulesCount += 1
6293
print("SG Rule Ingress Violation:", address, "has port", forbidden_port,
6394
"(RDP) open to", forbidden_cidrs, "that is not allowed")
64-
print(" Ingress Rule", "has to_port with value", sgr.change.after.to_port)
95+
print(" Ingress Rule has to_port with value", sgr.change.after.to_port)
96+
print(" The to_port and from_port both need to be set to an integer",
97+
"range or of equal")
98+
print(" value to each other that is either less than or greater than", forbidden_port)
6599
}
66100
} // end of SG Rules
67101

@@ -80,11 +114,6 @@ for allSGs as address, sg {
80114
violatingCidr = plan.filter_attribute_contains_items_from_list(ingressRules,
81115
"cidr_blocks", forbidden_cidrs, false)
82116

83-
# Filter to violating Service port
84-
# Warnings will not be printed for violations since the last parameter is false
85-
violatingToPort = plan.filter_attribute_is_value(ingressRules,
86-
"to_port", forbidden_to_port, false)
87-
88117
# Filter to violating Service port
89118
# Warnings will not be printed for violations since the last parameter is false
90119
violatingFromPortLess = plan.filter_attribute_less_than_equal_to_value(ingressRules,
@@ -104,14 +133,10 @@ for allSGs as address, sg {
104133
###Uncomment below if you want to show the CIDRs as a separate message as well
105134
# plan.print_violations(violatingCidr["messages"], " Ingress Rule")
106135
plan.print_violations(violatingFromPortLess["messages"], " Ingress Rule")
107-
plan.print_violations(violatingToPortGreater["messages"], " and Ingress Rule")
108-
} else if length(violatingCidr["messages"]) > 0 and length(violatingToPort["messages"]) > 0{
109-
violatingSGsCount += 1
110-
print("SG Ingress Violation:", address, "has port", forbidden_port,
111-
"(RDP) open to", forbidden_cidrs, "that is not allowed")
112-
###Uncomment below if you want to show the CIDRs as a separate message as well
113-
# plan.print_violations(violatingCidr["messages"], " Ingress Rule")
114-
plan.print_violations(violatingToPort["messages"], " Ingress Rule")
136+
plan.print_violations(violatingToPortGreater["messages"], " and Ingress Rule")
137+
print(" The to_port and from_port both need to be set to an integer",
138+
"range or of equal")
139+
print(" value to each other that is either less than or greater than", forbidden_port)
115140
}
116141
} // end for SGs
117142

governance/third-generation/aws/restrict-ingress-sg-rule-ssh.sentinel

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,50 @@ for aws_security_group_rules as address, sgr {
4040
# We check that it is present and really a list
4141
# before checking whether it contains "0.0.0.0/0"
4242
if sgr.change.after.cidr_blocks else null is not null and
43+
types.type_of(sgr.change.after.cidr_blocks) is "list" and
44+
sgr.change.after.cidr_blocks contains "0.0.0.0/0" and
45+
sgr.change.after.from_port else null is null and
46+
sgr.change.after.to_port else null is not null and
47+
sgr.change.after.to_port is forbidden_to_port{
48+
violatingSGRulesCount += 1
49+
print("SG Rule Ingress Violation:", address, "has port", forbidden_port,
50+
"(SSH) open to", forbidden_cidrs, "that is not allowed")
51+
print(" Ingress Rule has from_port that is null or undefined")
52+
print(" and Ingress Rule has to_port with value", sgr.change.after.to_port)
53+
print(" The to_port and from_port both need to be set to an integer",
54+
"range or of equal")
55+
print(" value to each other that is either less than or greater than", forbidden_port)
56+
} else if sgr.change.after.cidr_blocks else null is not null and
4357
types.type_of(sgr.change.after.cidr_blocks) is "list" and
4458
sgr.change.after.cidr_blocks contains "0.0.0.0/0" and
4559
sgr.change.after.from_port else null is not null and
46-
sgr.change.after.from_port <= forbidden_from_port and
60+
sgr.change.after.from_port is forbidden_from_port and
61+
sgr.change.after.to_port else null is null{
62+
violatingSGRulesCount += 1
63+
print("SG Rule Ingress Violation:", address, "has port", forbidden_port,
64+
"(SSH) open to", forbidden_cidrs, "that is not allowed")
65+
print(" Ingress Rule has from_port with value", sgr.change.after.from_port)
66+
print(" and Ingress Rule has to_port that is null or undefined")
67+
print(" The to_port and from_port both need to be set to an integer",
68+
"range or of equal")
69+
print(" value to each other that is either less than or greater than", forbidden_port)
70+
} else if sgr.change.after.cidr_blocks else null is not null and
71+
types.type_of(sgr.change.after.cidr_blocks) is "list" and
72+
sgr.change.after.cidr_blocks contains "0.0.0.0/0" and
73+
sgr.change.after.from_port else null is not null and
74+
sgr.change.after.from_port <= forbidden_from_port and
4775
sgr.change.after.to_port else null is not null and
4876
sgr.change.after.to_port >= forbidden_to_port{
4977
violatingSGRulesCount += 1
5078
print("SG Rule Ingress Violation:", address, "has port", forbidden_port,
5179
"(SSH) open to", forbidden_cidrs, "that is not allowed")
52-
print(" Ingress Rule", "has from_port with value", sgr.change.after.from_port,
80+
print(" Ingress Rule has from_port with value", sgr.change.after.from_port,
5381
"that is less than or equal to", forbidden_from_port)
54-
print(" and Ingress Rule has to_port with value", sgr.change.after.to_port,
82+
print(" and Ingress Rule has to_port with value", sgr.change.after.to_port,
5583
"that is greater than or equal to", forbidden_to_port)
84+
print(" The to_port and from_port both need to be set to an integer",
85+
"range or of equal")
86+
print(" value to each other that is either less than or greater than", forbidden_port)
5687
} else if sgr.change.after.cidr_blocks else null is not null and
5788
types.type_of(sgr.change.after.cidr_blocks) is "list" and
5889
sgr.change.after.cidr_blocks contains "0.0.0.0/0" and
@@ -61,7 +92,10 @@ for aws_security_group_rules as address, sgr {
6192
violatingSGRulesCount += 1
6293
print("SG Rule Ingress Violation:", address, "has port", forbidden_port,
6394
"(SSH) open to", forbidden_cidrs, "that is not allowed")
64-
print(" Ingress Rule", "has to_port with value", sgr.change.after.to_port)
95+
print(" Ingress Rule has to_port with value", sgr.change.after.to_port)
96+
print(" The to_port and from_port both need to be set to an integer",
97+
"range or of equal")
98+
print(" value to each other that is either less than or greater than", forbidden_port)
6599
}
66100
} // end of SG Rules
67101

@@ -80,11 +114,6 @@ for allSGs as address, sg {
80114
violatingCidr = plan.filter_attribute_contains_items_from_list(ingressRules,
81115
"cidr_blocks", forbidden_cidrs, false)
82116

83-
# Filter to violating Service port
84-
# Warnings will not be printed for violations since the last parameter is false
85-
violatingToPort = plan.filter_attribute_is_value(ingressRules,
86-
"to_port", forbidden_to_port, false)
87-
88117
# Filter to violating Service port
89118
# Warnings will not be printed for violations since the last parameter is false
90119
violatingFromPortLess = plan.filter_attribute_less_than_equal_to_value(ingressRules,
@@ -104,14 +133,10 @@ for allSGs as address, sg {
104133
###Uncomment below if you want to show the CIDRs as a separate message as well
105134
# plan.print_violations(violatingCidr["messages"], " Ingress Rule")
106135
plan.print_violations(violatingFromPortLess["messages"], " Ingress Rule")
107-
plan.print_violations(violatingToPortGreater["messages"], " and Ingress Rule")
108-
} else if length(violatingCidr["messages"]) > 0 and length(violatingToPort["messages"]) > 0{
109-
violatingSGsCount += 1
110-
print("SG Ingress Violation:", address, "has port", forbidden_port,
111-
"(SSH) open to", forbidden_cidrs, "that is not allowed")
112-
###Uncomment below if you want to show the CIDRs as a separate message as well
113-
# plan.print_violations(violatingCidr["messages"], " Ingress Rule")
114-
plan.print_violations(violatingToPort["messages"], " Ingress Rule")
136+
plan.print_violations(violatingToPortGreater["messages"], " and Ingress Rule")
137+
print(" The to_port and from_port both need to be set to an integer",
138+
"range or of equal")
139+
print(" value to each other that is either less than or greater than", forbidden_port)
115140
}
116141
} // end for SGs
117142

governance/third-generation/aws/test/restrict-ingress-sg-rule-rdp/mock-tfplan-fail.sentinel

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ resource_changes = {
1616
"from_port": 0,
1717
"ipv6_cidr_blocks": [],
1818
"prefix_list_ids": [],
19-
"protocol": "-1",
19+
"protocol": "tcp",
2020
"security_groups": [],
2121
"self": false,
22-
"to_port": 3389,
22+
"to_port": 9443,
2323
},
2424
],
2525
"name": "bar",
@@ -69,13 +69,13 @@ resource_changes = {
6969
"0.0.0.0/0",
7070
],
7171
"description": "baz",
72-
"from_port": 0,
72+
"from_port": null,
7373
"ipv6_cidr_blocks": [],
7474
"prefix_list_ids": [],
7575
"protocol": "tcp",
7676
"security_groups": [],
7777
"self": false,
78-
"to_port": 9443,
78+
"to_port": 3389,
7979
},
8080
],
8181
"name": "baz",
@@ -174,18 +174,42 @@ resource_changes = {
174174
"create",
175175
],
176176
"after": {
177-
"description": "seuss",
177+
"description": "seuss",
178+
"ingress": [
179+
{
180+
"cidr_blocks": [
181+
"0.0.0.0/0",
182+
],
183+
"description": "seuss",
184+
"from_port": 3389,
185+
"ipv6_cidr_blocks": [],
186+
"prefix_list_ids": [],
187+
"protocol": "tcp",
188+
"security_groups": [],
189+
"self": false,
190+
"to_port": null,
191+
},
192+
],
178193
"name": "seuss",
179194
"name_prefix": null,
180195
"revoke_rules_on_delete": false,
181196
"tags": null,
182197
"timeouts": null,
183198
},
184199
"after_unknown": {
185-
"arn": true,
186-
"egress": true,
187-
"id": true,
188-
"ingress": true,
200+
"arn": true,
201+
"egress": true,
202+
"id": true,
203+
"ingress": [
204+
{
205+
"cidr_blocks": [
206+
false,
207+
],
208+
"ipv6_cidr_blocks": [],
209+
"prefix_list_ids": [],
210+
"security_groups": [],
211+
},
212+
],
189213
"owner_id": true,
190214
"vpc_id": true,
191215
},
@@ -195,7 +219,7 @@ resource_changes = {
195219
"index": null,
196220
"mode": "managed",
197221
"module_address": "",
198-
"name": "seuss",
222+
"name": "foo",
199223
"provider_name": "aws",
200224
"type": "aws_security_group",
201225
},
@@ -215,7 +239,7 @@ resource_changes = {
215239
"prefix_list_ids": null,
216240
"protocol": "-1",
217241
"self": false,
218-
"to_port": 0,
242+
"to_port": 9443,
219243
"type": "ingress",
220244
},
221245
"after_unknown": {
@@ -247,7 +271,7 @@ resource_changes = {
247271
"0.0.0.0/0",
248272
],
249273
"description": "green",
250-
"from_port": 0,
274+
"from_port": 3389,
251275
"ipv6_cidr_blocks": null,
252276
"prefix_list_ids": null,
253277
"protocol": "tcp",
@@ -284,12 +308,12 @@ resource_changes = {
284308
"0.0.0.0/0",
285309
],
286310
"description": "ham",
287-
"from_port": 0,
311+
"from_port": null,
288312
"ipv6_cidr_blocks": null,
289313
"prefix_list_ids": null,
290314
"protocol": "tcp",
291315
"self": false,
292-
"to_port": 9443,
316+
"to_port": 3389,
293317
"type": "ingress",
294318
},
295319
"after_unknown": {
@@ -310,4 +334,41 @@ resource_changes = {
310334
"provider_name": "aws",
311335
"type": "aws_security_group_rule",
312336
},
313-
}
337+
"aws_security_group_rule.bar": {
338+
"address": "aws_security_group_rule.bar",
339+
"change": {
340+
"actions": [
341+
"create",
342+
],
343+
"after": {
344+
"cidr_blocks": [
345+
"0.0.0.0/0",
346+
],
347+
"description": "bar",
348+
"from_port": 3389,
349+
"ipv6_cidr_blocks": null,
350+
"prefix_list_ids": null,
351+
"protocol": "tcp",
352+
"self": false,
353+
"to_port": null,
354+
"type": "ingress",
355+
},
356+
"after_unknown": {
357+
"cidr_blocks": [
358+
false,
359+
],
360+
"id": true,
361+
"security_group_id": true,
362+
"source_security_group_id": true,
363+
},
364+
"before": null,
365+
},
366+
"deposed": "",
367+
"index": null,
368+
"mode": "managed",
369+
"module_address": "",
370+
"name": "bar",
371+
"provider_name": "aws",
372+
"type": "aws_security_group_rule",
373+
},
374+
}

0 commit comments

Comments
 (0)