Repository: Checkmarx/kics (language: python)

Issue:
skip/ignore/suppress resources for AWS CloudFormation
I want to skip the scan or ignore one particular rule from the below security group resource. 

```
Resources:
  DemoSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref myVPC
      GroupDescription: Ports open to the world
      SecurityGroupIngress:
        - Description: Allowing port 22 for everyone
          IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: "0.0.0.0/0"
        - Description: Allowing port 80 for everyone
          # kics-scan ignore-block 
          # I want to skip this rule
          IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: "0.0.0.0/0"
```

I tried it by adding commands in the command `# kics-scan ignore-line` or `# kics-scan ignore-block` but it is not working. I am not sure whether I am using it right. 

At the end of this [doc](https://docs.kics.io/latest/running-kics/#using_commands_on_scanned_files_as_comments) and it says, Currently, KICS supports this feature for:

Dockerfile;
HCL (Terraform);
YAML;

Suppressing resources/configuration is still not supported for CloudFormation with KICS Scan ? If it's supported, Can anyone please help me on this ?

Thank you.


Discussion / hints:
Hello.

You are using `# kics-scan ignore-block` wrong. You need to put before `SecurityGroupIngress:`, `Properties:`, `DemoSecurityGroup:` or `Resources:`. **EDIT: Because there is no block after that comment, just a few lines. A block is like an element of array like:
Description: Allowing port 22 for everyone
IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: "0.0.0.0/0"
or an Object with attributes (like Resources, DemoSecurityGroup, Properties or SecurityGroupIngress**

I notice that 5 HIGH vulnerabilities are pointing to the same line (`SecurityGroupIngress:`). So, you can put  `# kics-scan ignore-block` or  `# kics-scan ignore-line` before that line


Best regards
I got that part from the documentation but I do not want to ignore all the rules mentioned in the `SecurityGroupIngress:` block.

What I am looking for is, Out of two security rules, KICS should ignore one rule (For Port 80) and should scan all other rules mentioned in the resource. 

Following rule should be ignored/skip.

```
        - Description: Allowing port 80 for everyone
          IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: "0.0.0.0/0"
```

But KICS should continue scan for the following rule:

```
        - Description: Allowing port 22 for everyone
          IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: "0.0.0.0/0"
```

Fix patch:
diff --git a/assets/queries/cloudFormation/aws/http_port_open/query.rego b/assets/queries/cloudFormation/aws/http_port_open/query.rego
index 5f53a4e8d33..5925503abeb 100644
--- a/assets/queries/cloudFormation/aws/http_port_open/query.rego
+++ b/assets/queries/cloudFormation/aws/http_port_open/query.rego
@@ -1,6 +1,7 @@
 package Cx
 
 import data.generic.cloudformation as cf_lib
+import data.generic.common as common_lib
 
 CxPolicy[result] {
 	docs := input.document[i]
@@ -13,6 +14,30 @@ CxPolicy[result] {
 	entireNetwork(rule)
 	isTCP(rule.IpProtocol)
 	rule.FromPort <= 80
+
+	result := {
+		"documentId": input.document[i].id,
+		"resourceType": resource.Type,
+		"resourceName": cf_lib.get_resource_name(resource, name),
+		"searchKey": sprintf("%s%s.Properties.SecurityGroupIngress", [cf_lib.getPath(path),name]),
+		"searchLine": common_lib.build_search_line(["Resources", name, "Properties", "SecurityGroupIngress", index, "FromPort"], []),
+		"issueType": "IncorrectValue",
+		"keyExpectedValue": sprintf("Resources.%s.Properties.SecurityGroupIngress[%d] should not open the HTTP port (80)", [name, index]),
+		"keyActualValue": sprintf("Resources.%s.Properties.SecurityGroupIngress[%d] opens the HTTP port (80)", [name, index]),
+	}
+}
+
+
+CxPolicy[result] {
+	docs := input.document[i]
+	[path, Resources] := walk(docs)
+	resource := Resources[name]
+	resource.Type == "AWS::EC2::SecurityGroup"
+
+	rule := resource.Properties.SecurityGroupIngress[index]
+
+	entireNetwork(rule)
+	isTCP(rule.IpProtocol)
 	rule.ToPort >= 80
 
 	result := {
@@ -20,6 +45,7 @@ CxPolicy[result] {
 		"resourceType": resource.Type,
 		"resourceName": cf_lib.get_resource_name(resource, name),
 		"searchKey": sprintf("%s%s.Properties.SecurityGroupIngress", [cf_lib.getPath(path),name]),
+		"searchLine": common_lib.build_search_line(["Resources", name, "Properties", "SecurityGroupIngress", index, "ToPort"], []),
 		"issueType": "IncorrectValue",
 		"keyExpectedValue": sprintf("Resources.%s.Properties.SecurityGroupIngress[%d] should not open the HTTP port (80)", [name, index]),
 		"keyActualValue": sprintf("Resources.%s.Properties.SecurityGroupIngress[%d] opens the HTTP port (80)", [name, index]),
@@ -38,4 +64,4 @@ isTCP("tcp") = true
 
 isTCP("-1") = true
 
-isTCP("6") = true
+isTCP("6") = true
\ No newline at end of file
diff --git a/assets/queries/cloudFormation/aws/unrestricted_security_group_ingress/query.rego b/assets/queries/cloudFormation/aws/unrestricted_security_group_ingress/query.rego
index fdc28e9c055..2600cdd077f 100644
--- a/assets/queries/cloudFormation/aws/unrestricted_security_group_ingress/query.rego
+++ b/assets/queries/cloudFormation/aws/unrestricted_security_group_ingress/query.rego
@@ -1,6 +1,7 @@
 package Cx
 
 import data.generic.cloudformation as cf_lib
+import data.generic.common as common_lib
 
 CxPolicy[result] {
 	docs := input.document[i]
@@ -59,6 +60,7 @@ CxPolicy[result] {
 		"resourceType": resource.Type,
 		"resourceName": cf_lib.get_resource_name(resource, name),
 		"searchKey": sprintf("%s%s.Properties.SecurityGroupIngress", [cf_lib.getPath(path),name]),
+		"searchLine": common_lib.build_search_line(["Resources", name, "Properties", "SecurityGroupIngress", index, "CidrIp"], []),
 		"issueType": "IncorrectValue",
 		"keyExpectedValue": sprintf("Resources.%s.Properties.SecurityGroupIngress[%d].CidrIp should not be open to the world (0.0.0.0/0)", [name, index]),
 		"keyActualValue": sprintf("Resources.%s.Properties.SecurityGroupIngress[%d].CidrIp is open to the world (0.0.0.0/0)", [name, index]),
@@ -80,8 +82,9 @@ CxPolicy[result] {
 		"resourceType": resource.Type,
 		"resourceName": cf_lib.get_resource_name(resource, name),
 		"searchKey": sprintf("%s%s.Properties.SecurityGroupIngress[%d].CidrIpv6", [cf_lib.getPath(path),name, index]),
+		"searchLine": common_lib.build_search_line(["Resources", name, "Properties", "SecurityGroupIngress", index, "CidrIpv6"], []),
 		"issueType": "IncorrectValue",
 		"keyExpectedValue": sprintf("Resources.%s.Properties.SecurityGroupIngress[%d].CidrIpv6 should not be open to the world (::/0)", [name, index]),
 		"keyActualValue": sprintf("Resources.%s.Properties.SecurityGroupIngress[%d].CidrIpv6 is open to the world (::/0)", [name, index]),
 	}
-}
+}
\ No newline at end of file


Test patch:
diff --git a/assets/queries/cloudFormation/aws/http_port_open/test/positive_expected_result.json b/assets/queries/cloudFormation/aws/http_port_open/test/positive_expected_result.json
index 5b257a05962..e417982e9b2 100644
--- a/assets/queries/cloudFormation/aws/http_port_open/test/positive_expected_result.json
+++ b/assets/queries/cloudFormation/aws/http_port_open/test/positive_expected_result.json
@@ -2,13 +2,25 @@
   {
     "queryName": "HTTP Port Open To Internet",
     "severity": "HIGH",
-    "line": 8,
+    "line": 10,
     "fileName": "positive1.yaml"
   },
+  {
+    "queryName": "HTTP Port Open To Internet",
+    "severity": "HIGH",
+    "line": 11,
+    "fileName": "positive1.yaml"
+  },
+  {
+    "fileName": "positive2.json",
+    "queryName": "HTTP Port Open To Internet",
+    "severity": "HIGH",
+    "line": 13
+  },
   {
     "fileName": "positive2.json",
     "queryName": "HTTP Port Open To Internet",
     "severity": "HIGH",
-    "line": 10
+    "line": 14
   }
-]
+]
\ No newline at end of file
diff --git a/assets/queries/cloudFormation/aws/unrestricted_security_group_ingress/test/positive_expected_result.json b/assets/queries/cloudFormation/aws/unrestricted_security_group_ingress/test/positive_expected_result.json
index 21ab80d3e15..8436a1ff378 100644
--- a/assets/queries/cloudFormation/aws/unrestricted_security_group_ingress/test/positive_expected_result.json
+++ b/assets/queries/cloudFormation/aws/unrestricted_security_group_ingress/test/positive_expected_result.json
@@ -2,7 +2,7 @@
   {
     "queryName": "Unrestricted Security Group Ingress",
     "severity": "HIGH",
-    "line": 8,
+    "line": 13,
     "fileName": "positive1.yaml"
   },
   {
@@ -20,7 +20,7 @@
   {
     "queryName": "Unrestricted Security Group Ingress",
     "severity": "HIGH",
-    "line": 53,
+    "line": 56,
     "fileName": "positive2.json"
   }
-]
+]
\ No newline at end of file