fix(query): fn for remote desktop port open to internet and other "security group" associated queries --terraform/aws--cloudformation/aws#7646
Conversation
…09541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…_Internet--terraform/aws
…09541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…rraform/aws' of https://github.com/Checkmarx/kics into AST-109541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…_Internet--terraform/aws
…_Internet--terraform/aws
…_Internet--terraform/aws
…09542--FN-Sensitive_Port_Is_Exposed_To_Entire_Network--terraform/aws
…09541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…ork--terraform/aws' into AST-109541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…rraform/aws' of https://github.com/Checkmarx/kics into AST-109541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…nrestricted_security_group_ingress final changes
…_Internet--terraform/aws
…_Internet--terraform/aws
…09541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…_Internet--terraform/aws
…_Internet--terraform/aws
…_Internet--terraform/aws
…_Internet--terraform/aws
cx-artur-ribeiro
left a comment
There was a problem hiding this comment.
Hey André, insane job you did here. From the new cases to the auxiliary functions and search lines, you showed great judgment in making these changes. I left a few comments for possible improvements, take a look and see what you think/if you agree.
assets/queries/terraform/aws/sensitive_port_is_exposed_to_small_public_network/query.rego
Outdated
Show resolved
Hide resolved
assets/queries/terraform/aws/sensitive_port_is_exposed_to_small_public_network/query.rego
Outdated
Show resolved
Hide resolved
assets/queries/terraform/aws/security_group_without_description/query.rego
Outdated
Show resolved
Hide resolved
assets/queries/terraform/aws/unrestricted_security_group_ingress/query.rego
Outdated
Show resolved
Hide resolved
assets/queries/terraform/aws/unrestricted_security_group_ingress/query.rego
Outdated
Show resolved
Hide resolved
assets/queries/terraform/aws/unrestricted_security_group_ingress/query.rego
Outdated
Show resolved
Hide resolved
assets/queries/terraform/aws/unrestricted_security_group_ingress/query.rego
Outdated
Show resolved
Hide resolved
assets/queries/terraform/aws/unrestricted_security_group_ingress/query.rego
Outdated
Show resolved
Hide resolved
…rraform/aws' of https://github.com/Checkmarx/kics into AST-109541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…_Internet--terraform/aws
…_Internet--terraform/aws
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 20838717 | Triggered | Generic Password | 24678a5 | assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative7.json | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
…_Internet--terraform/aws
…rraform/aws' of https://github.com/Checkmarx/kics into AST-109541--FN-Remote_Desktop_Port_Open_To_Internet--terraform/aws
…_Internet--terraform/aws








Reason for Proposed Changes
Currently the "Remote Desktop Port Open To Internet" terraform query will only flag if the exposed port is defined as an inline "ingress" rule of an "aws_security_group" resource.
This leaves out any "aws_vpc_security_group_ingress_rule" that should also be flagged; in fact
"Using aws_vpc_security_group_egress_rule and aws_vpc_security_group_ingress_rule resources is the current best practice"as stated in the official documentation.For a given "ingress" rule to be considered open it must be evaluated as "true" by the function "portOpenToInternet" from the terraform library.
The auxiliary function checks that the
"cidr_blocks"field contains"0.0.0.0/0"or equivilant IP, then the"protocol"field must be set to"tcp"and, finnaly, the port, in this case 3389, has to be included in the range determined by the"from_port"and"to_port"fields.This issue was raised followed by several identical ones that apply to other terraform queries. This sparked an investigation into the full scope of queries in need of updating for ingress/egress rules as resources. Both terraform and cloudformation queries require this update. Cloudformation equivalent resources:
The cloudformation queries will be handled through a separate PR to facilitate review processes.
Affected Terraform Queries :
Aside from the "aws_vpc_security_group_ingress_rule" resource the "aws_vpc_security_group_egress_rule" is also relevant and unsupported for some queries and for a large amount of them the "security-group" module is relevant but completely unsupported, if supported it is also missing Ipv6 support. IPv6 support is also lacking for the mentioned resources and the "aws_security_group" resource.
Proposed Changes
assets\librariescommon.regoterraform.regoAdded "is_security_group_ingress" helper function to check that an aws security group "rule"(generic or explicit) is an ingress rule.
Added "cidr_is_unmasked" to check that the mask of an ip address is == "/0", made to support all possible cidr_block declarations associated with security groups.
Improved the "portOpenToInternet" function to support the naming scheme present in the
aws_vpc_security_group_ingress_rule/aws_vpc_security_group_egress_ruleresources which is as follows (compared to in-lineaws_security_groupingress):ingress.cidr_block ==aws_vpc_security_group_ingress_rule.cidr_ipv4ingress.ipv6_cidr_blocks ==aws_vpc_security_group_ingress_rule.cidr_ipv6ingress.protocol ==aws_vpc_security_group_ingress_rule.ip_protocolThis equivalences are not one to one since the "aws_vpc_security_group_ingress_rule" cidr will always be a single string, it is not a string array like the Ingress's "cidr_blocks".
I updated the "portOpenToInternet" and "check_cidr" functions to support the new resource, note that for the "portOpenToInternet" function, when checking a "ip_protocol", "tcp" is no longer the only valid value; the documentation states a value of "-1"
"translates to all protocols, all port ranges"; to furthur prove this point the documentation for the aws_security_group resource explicitly states "-1" is not a valid value for the Igress's "protocol" field which explains why it is not checked for in the current auxiliary function.The generic security_group_rule allows "-1" values for a "protocol" field and the check for port range is not done when "-1" is set because setting this value ignores the port ranges altogether. The documentation states:
"Setting protocol = "all" or protocol = -1 with from_port and to_port will result in the EC2 API creating a security group rule with all ports open. This API behavior cannot be controlled by Terraform and may generate warnings in the future."For security group ingress rules the documentation states:
"(Required) Protocol. If you select a protocol of -1 (semantically equivalent to all, which is not a valid value here), you must specify a from_port and to_port equal to 0."It seems using "-1" and "all" can lead to unexpected results but given the context it sounds as though any protocol set to this value should be flagged regardless of port ranges.
Finally the new "get_ingress_list" function was created to simplify and unify case handling of "ingress" blocks so that a single CxPolicy can deal with either an individual "ingress" block and an array of them inside an "aws_security_group" resource.
assets/querieshttp_port_open: Current Implementation / Documentationsecurity_group_with_unrestricted_access_to_ssh: Current Implementation / Documentationremote_desktop_port_open_to_internet: Current Implementation / Documentationsql_analysis_services_port_2383_is_publicly_accessible: Current Implementation / DocumentationThese queries were grouped since their implementation is near identical and so were the adjustments made to them as a result. All of them rely on the auxiliar
portOpenToInternetfunction to flag in case a specific port is exposed.Test files have been adjusted for all the new case scenarios and have been made as similar as possible to facilitate review and future alterations. The queries implementation itself was also altered to be as similar as possible between the 4 of them.
For all these queries support for "aws_vpc_security_group_ingress_rule" and "aws_security_group_rule" was not present and was added through a single CxPolicy. Support for ipv6 addresses was also ensured. For module support only
security_group_with_unrestricted_access_to_sshhad it and it did not take ipv6 into account.All the queries now support modules in a single CxPolicy (ssh query had 2 for array handling which is now delegated to helper functions). The original functions, with the exception of "ssh", only accounted for "aws_security_group" resources and did not have case handling in case there was more than a single ingress associated with said group and without ipv6 support.
The queries use 3 CxPolicy to cover these scenarios relying on equivalent helper functions like "http_is_open" to return "search" and "key" values.
sensitive_port_is_exposed_to_entire_network: Current Implementation / Documentationsensitive_port_is_exposed_to_small_public_network: Current Implementation / Documentationsensitive_port_is_exposed_to_wide_private_network: Current Implementation / DocumentationAs their name implies this queries are also very similar in nature but their current implementations are varied. The simplest one is the "small public network" query, the implementation for it is very limited only being valid for "aws_security_group" resources with a single "ingress" block.
For the "entire network" query, the "aws_security_group" resource is also the only one supported but there are 2 CxPolicy to handle multiple ingress blocks for a single resource.
Finally the "wide private network" query once again only supports a single "ingress" block per "aws_security_group" resource, but has support for modules(ipv4).
All the implementations are lacking support for ipv6 fields and "aws_vpc_security_group_ingress_rule" and "aws_security_group_rule" resources.
The "isSmallPublicNetwork" helper function (
sensitive_port_is_exposed_to_small_public_network) needed to include new "prefixes" to qualify as small network since, for an ipv4 address a /25 mask means 128 total addressable hosts but to an ipv6 network it means ~1.01 × 10³¹. The scales are completely different so, to correspond with the /25 to /29 values used for ipv4, ipv6 links are checked for masks ranging from /121 to /125.The "isPrivateNetwork" helper function (
sensitive_port_is_exposed_to_wide_private_network) was also tweaked to check for all possible "cidr" field names; the "isPrivateIP" function from the common library was updated to allow ipv6 support in this query.Test structure for Group 1 and 2
Group 3 - description queries
security_group_rules_without_description: Current Implementation / Documentationsecurity_group_without_description: Current Implementation / DocumentationI started by updating the
security_group_rules_without_descriptionquery and later realized thesecurity_group_without_descriptionwas missing a check for modules too. This queries are structured so that the "group_rules" query checks for all "egress" and "ingress" blocks inside "aws_security_group" resources as well as all "aws_security_group_rule" resources and flags in case they are missing a description.This current implementation was missing the case of "aws_vpc_security_group_ingress_rule" and "aws_vpc_security_group_egress_rule" resources. Additionally it was not checking for the equivalent "rules" inside the relevant module those being "egress_with_cidr_blocks/egress_with_ipv6_cidr_blocks" and "ingress_with_cidr_blocks/ingress_with_ipv6_cidr_blocks".
For the
security_group_without_descriptioni added the check for the description field of the "security-group" module itself.For testing a positive2/negative2 with a simple sample with a "module" was added to the
security_group_without_descriptionquery; and for thesecurity_group_rules_without_descriptionthe positive1-3 and negative1-3 testes were kept pretty much unchanged; new positive4/negative4 tests were added for "aws_vpc_security_group_ingress_rule" resources and positive5/negative5 tests for "security-group" modules.unknown_port_exposed_to_internet: Current Implementation / DocumentationThis query, currently, only works for "aws_security_group" ingress blocks. It checks that a port range (from x to x) includes unknown ports , as in any port not specified within the "tcpPortsMap" map of the common library, and that the cidr includes "0.0.0.0/0".
The current implementation is shallow missing not only ipv6 handling but also "aws_security_group_rule", "aws_vpc_security_group_ingress_rule" and "security-group" module support. The "check_cidr" terraform library function will allow ipv6 open addresses to be detected. New CxPolicy(s) for modules and rules were added. The new comprehensive test files follow the 1-4 structure defined for Group 1 and 2.
unrestricted_security_group_ingress: Current Implementation / DocumentationThe number of CxPolicy(s) for the current implementation of this query is very high; it handles a lot of scenarios : "aws_security_group_rule"(ipv4/ipv6), "aws_security_group"(single ingress and array + ipv4/ipv6), modules with "ingress_cidr_blocks" and "ingress_ipv6_cidr_blocks". It uses a new CxPolicy for every valid scenario (8).
The new implementation has lowered the CxPolicy ammount to just 3 while relying on some big helper functions. This query stands out from the other due to the fact that the "cidr" fields can and should be pointed to by the "key" and "search" values in the results; this adds some complexity since the "cidr" fields have different names depending on context.
A new case was also added to the modules since the original implementation was not taking into account "ingress_with_cidr_blocks" and "ingress_with_ipv6_cidr_blocks" which allow for a full ingress block to be defined inside the module and not just "cidr" values like the "ingress_cidr_blocks" and "ingress_ipv6_cidr_blocks" that were already accounted for.
Original test files were adjusted to follow the standard 1-4 described in "Group 1 and 2".
Final Notes
Fixs Post Merger:
I submit this contribution under the Apache-2.0 license.