This repository has been archived by the owner on Sep 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RM-6342] ARM template support (#278)
* Initial ARM support * [RM-6342] Fix build error * [RM-6342] Cleanup branch * [RM-6342] Add rule, test, and input skeletons (#257) * [RM-6342] Add rule, test, and input skeletons * [RM-6342] Add CIS-Azure mappings * [RM-6342] Fix reference in test * [RM-6366] ARM resource view update & rules for database firewalls This adds a refinement of the resource view, and three rules: - FG_R00221 SQL Server firewall rules should not permit start and end IP addresses to be 0.0.0.0 - FG_R00222 MySQL Database server firewall rules should not permit start and end IP addresses to be 0.0.0.0 - FG_R00223 PostgreSQL Database server firewall rules should not permit start and end IP addresses to be 0.0.0.0 * [RM-6366] Update tests * [RM-6342] Add ARM authorization rule (#262) * [RM-6366] Add database enforce SSL rules * [RM-6342] Add ARM app_service rules (#260) * [RM-6342] Add ARM app_service rules * [RM-6342] Use number[] comparison for min TLS version * [RM-6342] Add ARM key_vault rule (#263) * [RM-6366] Add ARM no inbound 22/3389 rules * [RM-6342] Add ARM kubernetes rule (#264) * [RM-6342] Add ARM storage rules (#266) * [RM-6366] Add gateway_waf_enabled and flow_log_retention ARM network rules * Add arm/network/app_gateway_waf_enabled rule * Add arm/network/flow_log_retention rule * [RM-6366] Add PostgreSQL configuration rules * [RM-6366] Add ARM SQL auditing rules * [RM-6387] Add ARM monitor rules (#270) * [RM-6387] Add ARM monitor rules * [RM-6387] Use tokenize to find key vault name * [RM-6366] Add ARM VM disk encryption rules * [RM-6387] Add ARM app_service "Register with Azure Active Directory" rule (#272) * [RM-6366] Add arm/key_vault/secret_expiry rule * [RM-6387] Add ARM securty contact notifications rule (#274) * [RM-6342] Add arm to inline docs * [RM-6366] Add arm/storage/account_queue_logging rule (#277) * [RM-6414] Update some Azure rule descriptions (#276) * [RM-6414] Update some Azure rule descriptions * [RM-6414] Fix quotes * [RM-6342] Add changelog entry * [RM-6342] Fix indentation in help text Co-authored-by: Richard Park <[email protected]> Co-authored-by: Jasper Van der Jeugt <[email protected]>
- Loading branch information
1 parent
961732a
commit 1b90453
Showing
152 changed files
with
9,990 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
kind: Added | ||
body: Azure Resource Manager (ARM) template support with 38 rules. This feature is | ||
currently in preview. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Copyright 2021 Fugue, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package loader | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
) | ||
|
||
var validArmExts map[string]bool = map[string]bool{ | ||
".json": true, | ||
} | ||
|
||
type ArmDetector struct{} | ||
|
||
func (c *ArmDetector) DetectFile(i InputFile, opts DetectOptions) (IACConfiguration, error) { | ||
if !opts.IgnoreExt && !validArmExts[i.Ext()] { | ||
return nil, fmt.Errorf("File does not have .json extension: %v", i.Path()) | ||
} | ||
contents, err := i.Contents() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
template := &armTemplate{} | ||
if err := json.Unmarshal(contents, &template.Contents); err != nil { | ||
return nil, fmt.Errorf("Failed to parse file as JSON %v: %v", i.Path(), err) | ||
} | ||
_, hasSchema := template.Contents["$schema"] | ||
_, hasResources := template.Contents["resources"] | ||
|
||
if !hasSchema && !hasResources { | ||
return nil, fmt.Errorf("Input file is not an ARM template: %v", i.Path()) | ||
} | ||
path := i.Path() | ||
|
||
return &armConfiguration{ | ||
path: path, | ||
template: *template, | ||
}, nil | ||
} | ||
|
||
func (c *ArmDetector) DetectDirectory(i InputDirectory, opts DetectOptions) (IACConfiguration, error) { | ||
return nil, nil | ||
} | ||
|
||
type armConfiguration struct { | ||
path string | ||
template armTemplate | ||
source *SourceInfoNode | ||
} | ||
|
||
func (l *armConfiguration) RegulaInput() RegulaInput { | ||
return RegulaInput{ | ||
"filepath": l.path, | ||
"content": l.template.Contents, | ||
} | ||
} | ||
|
||
func (l *armConfiguration) Location(path []string) (LocationStack, error) { | ||
if l.source == nil || len(path) < 1 { | ||
return nil, nil | ||
} | ||
|
||
resourcePath := []string{"Resources"} | ||
resourcePath = append(resourcePath, path[0]) | ||
resource, err := l.source.GetPath(resourcePath) | ||
if err != nil { | ||
return nil, nil | ||
} | ||
resourceLine, resourceColumn := resource.Location() | ||
resourceLocation := Location{ | ||
Path: l.path, | ||
Line: resourceLine, | ||
Col: resourceColumn, | ||
} | ||
|
||
properties, err := resource.GetKey("Properties") | ||
if err != nil { | ||
return []Location{resourceLocation}, nil | ||
} | ||
|
||
attribute, err := properties.GetPath(path[1:]) | ||
if attribute != nil { | ||
return []Location{resourceLocation}, nil | ||
} | ||
|
||
line, column := attribute.Location() | ||
return []Location{{Path: l.path, Line: line, Col: column}}, nil | ||
} | ||
|
||
func (l *armConfiguration) LoadedFiles() []string { | ||
return []string{l.path} | ||
} | ||
|
||
type armTemplate struct { | ||
Contents map[string]interface{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Copyright 2020 Fugue, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
# This helper rego code works for Azure "no ingress" rules. | ||
# It is built on top of the terraform code that does the same, | ||
# through a simple conversion (`rule_to_tf`). | ||
package fugue.arm.disk_encryption_library | ||
|
||
import data.fugue | ||
|
||
disks := fugue.resources("Microsoft.Compute/disks") | ||
|
||
virtual_machines := fugue.resources("Microsoft.Compute/virtualMachines") | ||
|
||
data_disk_ids := {id | | ||
disk := virtual_machines[_].properties.storageProfile.dataDisks[_] | ||
id := disk.managedDisk.id | ||
} | ||
|
||
os_disk_ids := {id | | ||
id := virtual_machines[_].properties.storageProfile.osDisk.managedDisk.id | ||
} | ||
|
||
unattached_disk_ids := {id | | ||
_ := disks[id] | ||
not data_disk_ids[id] | ||
not os_disk_ids[id] | ||
} | ||
|
||
disk_encrypted(disk) { | ||
disk.properties.encryptionSettingsCollection.enabled == true | ||
} | ||
|
||
disk_encrypted(disk) { | ||
des_id := disk.properties.encryption.diskEncryptionSetId | ||
is_string(des_id) | ||
des_id != "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# Copyright 2020 Fugue, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
# This helper rego code works for Azure "no ingress" rules. | ||
# It is built on top of the terraform code that does the same, | ||
# through a simple conversion (`rule_to_tf`). | ||
package fugue.arm.network_security_group_library | ||
|
||
import data.fugue | ||
import data.fugue.azure.network_security_group as tf | ||
|
||
rule_to_tf(arm_rule) = ret { | ||
# We only pass in the attributes we actually use. | ||
props = arm_rule.properties | ||
ret := { | ||
"access": props.access, | ||
"direction": props.direction, | ||
"destination_port_range": object.get(props, "destinationPortRange", null), | ||
"destination_port_ranges": object.get(props, "destinationPortRanges", []), | ||
"source_address_prefix": object.get(props, "sourceAddressPrefix", null), | ||
"source_address_prefixes": object.get(props, "sourceAddressPrefixes", null), | ||
} | ||
} | ||
|
||
rule_allows_anywhere_to_port(rule, bad_port) { | ||
tf.rule_allows_anywhere_to_port(rule_to_tf(rule), bad_port) | ||
} | ||
|
||
group_allows_anywhere_to_port(group, bad_port) { | ||
rule = group.properties.securityRules[_] | ||
tf.rule_allows_anywhere_to_port(rule_to_tf(rule), bad_port) | ||
} | ||
|
||
no_inbound_anywhere_to_port_policy(port) = ret { | ||
security_groups := fugue.resources("Microsoft.Network/networkSecurityGroups") | ||
security_groups_policy = {p | | ||
security_group := security_groups[_] | ||
group_allows_anywhere_to_port(security_group, port) | ||
p := fugue.deny_resource(security_group) | ||
} | {p | | ||
security_group := security_groups[_] | ||
not group_allows_anywhere_to_port(security_group, port) | ||
p := fugue.allow_resource(security_group) | ||
} | ||
|
||
security_rules := fugue.resources("Microsoft.Network/networkSecurityGroups/securityRules") | ||
security_rules_policy = {p | | ||
security_rule := security_rules[_] | ||
rule_allows_anywhere_to_port(security_rule, port) | ||
p := fugue.deny_resource(security_rule) | ||
} | {p | | ||
security_rule := security_rules[_] | ||
not rule_allows_anywhere_to_port(security_rule, port) | ||
p := fugue.allow_resource(security_rule) | ||
} | ||
|
||
ret := security_groups_policy | security_rules_policy | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Copyright 2021 Fugue, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
package fugue.arm.postgresql_configuration_library | ||
|
||
import data.fugue | ||
|
||
servers = fugue.resources("Microsoft.DBforPostgreSQL/servers") | ||
|
||
configurations = fugue.resources("Microsoft.DBforPostgreSQL/servers/configurations") | ||
|
||
configuration_defaults := { | ||
"connection_throttling": "on", | ||
"log_checkpoints": "on", | ||
"log_connections": "on", | ||
"log_disconnections": "off", | ||
"log_duration": "off", | ||
"log_retention_days": "3", | ||
} | ||
|
||
configuration_by_server_id := {server_id: configuration | | ||
server := servers[server_id] | ||
configuration := {name: value | | ||
option := configurations[_] | ||
option._parent_id == server_id | ||
id_parts := split(option.id, "/") | ||
name := id_parts[count(id_parts) - 1] | ||
value := option.properties.value | ||
} | ||
} | ||
|
||
configuration_value(server, name) = ret { | ||
ret := configuration_by_server_id[server.id][name] | ||
} else = ret { | ||
ret := configuration_defaults[name] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.