We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
CKV_AWS_118 Fails With MonitoringInterval Integer Value
**Describe the issue**
CKV_AWS_118 fails if the `MonitoringInterval` value is not wrapped in double quotes despite the fact that the source code says it should allow ints and strings.

**Examples**
```
RDSinstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBClusterIdentifier: !Ref DBCluster
      DBInstanceClass: !Ref DbType
      DBInstanceIdentifier: !Sub ${AppName}-${EnvironmentName}
      DBParameterGroupName: !Ref DbParameterGroup
      DBSubnetGroupName: !Ref DBSubnetGroup
      Engine: aurora-mysql
      MonitoringInterval: 60
      MonitoringRoleArn: !GetAtt RdsMonitoringRole.Arn
      PubliclyAccessible: 'false'
```

**Version (please complete the following information):**
 - Checkov Version 2.2.255 (CLI)

**Additional context**
The test failure happens with the CLI and also using a GItHub Action `bridgecrewio/checkov-action@master`

![Screenshot 2023-01-13 at 8 52 02 AM](https://user-images.githubusercontent.com/1328683/212362109-7c0d3751-08e4-4428-9120-37edf3e85f88.png)



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `checkov/cloudformation/checks/resource/base_resource_value_check.py`
Content:
```
1 import re
2 from abc import abstractmethod
3 from collections.abc import Iterable
4 from typing import List, Any, Dict
5 
6 from checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck
7 from checkov.cloudformation.context_parser import ContextParser
8 from checkov.common.parsers.node import StrNode, DictNode
9 from checkov.common.models.consts import ANY_VALUE
10 from checkov.common.models.enums import CheckResult, CheckCategories
11 from checkov.common.util.type_forcers import force_list
12 from checkov.common.util.var_utils import is_cloudformation_variable_dependent
13 
14 VARIABLE_DEPENDANT_REGEX = re.compile(r"(?:Ref)\.[^\s]+")
15 
16 
17 class BaseResourceValueCheck(BaseResourceCheck):
18     def __init__(
19         self,
20         name: str,
21         id: str,
22         categories: "Iterable[CheckCategories]",
23         supported_resources: "Iterable[str]",
24         missing_block_result: CheckResult = CheckResult.FAILED,
25     ) -> None:
26         super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
27         self.missing_block_result = missing_block_result
28 
29     @staticmethod
30     def _filter_key_path(path: str) -> List[str]:
31         """
32         Filter an attribute path to contain only named attributes by dropping array indices from the path)
33         :param path: valid JSONPath of an attribute
34         :return: List of named attributes with respect to the input JSONPath order
35         """
36         regex = re.compile(r"^\[?\d+\]?$")
37         return [x for x in path.split("/") if not re.search(regex, x)]
38 
39     @staticmethod
40     def _is_variable_dependant(value: Any) -> bool:
41         return is_cloudformation_variable_dependent(value)
42 
43     @staticmethod
44     def _is_nesting_key(inspected_attributes: List[str], key: str) -> bool:
45         """
46         Resolves whether a key is a subset of the inspected nesting attributes
47         :param inspected_attributes: list of nesting attributes
48         :param key: JSONPath key of an attribute
49         :return: True/False
50         """
51         return any(x in key for x in inspected_attributes)
52 
53     def scan_resource_conf(self, conf: Dict[StrNode, DictNode]) -> CheckResult:
54         inspected_key = self.get_inspected_key()
55         expected_values = self.get_expected_values()
56         path_elements = inspected_key.split("/")
57         matches = ContextParser.search_deep_keys(path_elements[-1], conf, [])
58         if len(matches) > 0:
59             for match in matches:
60                 # CFN files are parsed differently from terraform, which causes the path search above to behave differently.
61                 # The tesult is path parts with integer indexes, instead of strings like '[0]'. This logic replaces
62                 # those, allowing inspected_keys in checks to use the same syntax.
63                 for i in range(0, len(match)):
64                     if type(match[i]) == int:
65                         match[i] = f"[{match[i]}]"
66 
67                 if match[:-1] == path_elements:
68                     # Inspected key exists
69                     value = match[-1]
70                     if ANY_VALUE in expected_values and value is not None and (not isinstance(value, str) or value):
71                         # Key is found on the configuration - if it accepts any value, the check is PASSED
72                         return CheckResult.PASSED
73                     if isinstance(value, list) and len(value) == 1:
74                         value = value[0]
75                     if self._is_variable_dependant(value):
76                         # If the tested attribute is variable-dependant, then result is PASSED
77                         return CheckResult.PASSED
78                     if value in expected_values:
79                         return CheckResult.PASSED
80 
81                     # handle boolean case sensitivity (e.g., CFN accepts the string "true" as a boolean)
82                     if isinstance(value, str) and value.lower() in ('true', 'false'):
83                         value = value.lower() == 'true'
84                         if value in expected_values:
85                             return CheckResult.PASSED
86                     return CheckResult.FAILED
87 
88         return self.missing_block_result
89 
90     @abstractmethod
91     def get_inspected_key(self) -> str:
92         """
93         :return: JSONPath syntax path of the checked attribute
94         """
95         raise NotImplementedError()
96 
97     def get_expected_values(self) -> List[Any]:
98         """
99         Override the method with the list of acceptable values if the check has more than one possible expected value, given
100         the inspected key
101         :return: List of expected values, defaults to a list of the expected value
102         """
103         return [self.get_expected_value()]
104 
105     def get_expected_value(self) -> Any:
106         """
107         Returns the default expected value, governed by provider best practices
108         """
109         return True
110 
111     def get_evaluated_keys(self) -> List[str]:
112         return force_list(self.get_inspected_key())
113
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/checkov/cloudformation/checks/resource/base_resource_value_check.py b/checkov/cloudformation/checks/resource/base_resource_value_check.py
--- a/checkov/cloudformation/checks/resource/base_resource_value_check.py
+++ b/checkov/cloudformation/checks/resource/base_resource_value_check.py
@@ -60,7 +60,8 @@
                 # CFN files are parsed differently from terraform, which causes the path search above to behave differently.
                 # The tesult is path parts with integer indexes, instead of strings like '[0]'. This logic replaces
                 # those, allowing inspected_keys in checks to use the same syntax.
-                for i in range(0, len(match)):
+                # The last value shouldn't be changed, because it could be indeed a valid number
+                for i in range(0, len(match) - 1):
                     if type(match[i]) == int:
                         match[i] = f"[{match[i]}]"

{"golden_diff": "diff --git a/checkov/cloudformation/checks/resource/base_resource_value_check.py b/checkov/cloudformation/checks/resource/base_resource_value_check.py\n--- a/checkov/cloudformation/checks/resource/base_resource_value_check.py\n+++ b/checkov/cloudformation/checks/resource/base_resource_value_check.py\n@@ -60,7 +60,8 @@\n                 # CFN files are parsed differently from terraform, which causes the path search above to behave differently.\n                 # The tesult is path parts with integer indexes, instead of strings like '[0]'. This logic replaces\n                 # those, allowing inspected_keys in checks to use the same syntax.\n-                for i in range(0, len(match)):\n+                # The last value shouldn't be changed, because it could be indeed a valid number\n+                for i in range(0, len(match) - 1):\n                     if type(match[i]) == int:\n                         match[i] = f\"[{match[i]}]\"\n", "issue": "CKV_AWS_118 Fails With MonitoringInterval Integer Value\n**Describe the issue**\r\nCKV_AWS_118 fails if the `MonitoringInterval` value is not wrapped in double quotes despite the fact that the source code says it should allow ints and strings.\r\n\r\n**Examples**\r\n```\r\nRDSinstance:\r\n    Type: AWS::RDS::DBInstance\r\n    Properties:\r\n      DBClusterIdentifier: !Ref DBCluster\r\n      DBInstanceClass: !Ref DbType\r\n      DBInstanceIdentifier: !Sub ${AppName}-${EnvironmentName}\r\n      DBParameterGroupName: !Ref DbParameterGroup\r\n      DBSubnetGroupName: !Ref DBSubnetGroup\r\n      Engine: aurora-mysql\r\n      MonitoringInterval: 60\r\n      MonitoringRoleArn: !GetAtt RdsMonitoringRole.Arn\r\n      PubliclyAccessible: 'false'\r\n```\r\n\r\n**Version (please complete the following information):**\r\n - Checkov Version 2.2.255 (CLI)\r\n\r\n**Additional context**\r\nThe test failure happens with the CLI and also using a GItHub Action `bridgecrewio/checkov-action@master`\r\n\r\n![Screenshot 2023-01-13 at 8 52 02 AM](https://user-images.githubusercontent.com/1328683/212362109-7c0d3751-08e4-4428-9120-37edf3e85f88.png)\r\n\r\n\n", "before_files": [{"content": "import re\nfrom abc import abstractmethod\nfrom collections.abc import Iterable\nfrom typing import List, Any, Dict\n\nfrom checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck\nfrom checkov.cloudformation.context_parser import ContextParser\nfrom checkov.common.parsers.node import StrNode, DictNode\nfrom checkov.common.models.consts import ANY_VALUE\nfrom checkov.common.models.enums import CheckResult, CheckCategories\nfrom checkov.common.util.type_forcers import force_list\nfrom checkov.common.util.var_utils import is_cloudformation_variable_dependent\n\nVARIABLE_DEPENDANT_REGEX = re.compile(r\"(?:Ref)\\.[^\\s]+\")\n\n\nclass BaseResourceValueCheck(BaseResourceCheck):\n    def __init__(\n        self,\n        name: str,\n        id: str,\n        categories: \"Iterable[CheckCategories]\",\n        supported_resources: \"Iterable[str]\",\n        missing_block_result: CheckResult = CheckResult.FAILED,\n    ) -> None:\n        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)\n        self.missing_block_result = missing_block_result\n\n    @staticmethod\n    def _filter_key_path(path: str) -> List[str]:\n        \"\"\"\n        Filter an attribute path to contain only named attributes by dropping array indices from the path)\n        :param path: valid JSONPath of an attribute\n        :return: List of named attributes with respect to the input JSONPath order\n        \"\"\"\n        regex = re.compile(r\"^\\[?\\d+\\]?$\")\n        return [x for x in path.split(\"/\") if not re.search(regex, x)]\n\n    @staticmethod\n    def _is_variable_dependant(value: Any) -> bool:\n        return is_cloudformation_variable_dependent(value)\n\n    @staticmethod\n    def _is_nesting_key(inspected_attributes: List[str], key: str) -> bool:\n        \"\"\"\n        Resolves whether a key is a subset of the inspected nesting attributes\n        :param inspected_attributes: list of nesting attributes\n        :param key: JSONPath key of an attribute\n        :return: True/False\n        \"\"\"\n        return any(x in key for x in inspected_attributes)\n\n    def scan_resource_conf(self, conf: Dict[StrNode, DictNode]) -> CheckResult:\n        inspected_key = self.get_inspected_key()\n        expected_values = self.get_expected_values()\n        path_elements = inspected_key.split(\"/\")\n        matches = ContextParser.search_deep_keys(path_elements[-1], conf, [])\n        if len(matches) > 0:\n            for match in matches:\n                # CFN files are parsed differently from terraform, which causes the path search above to behave differently.\n                # The tesult is path parts with integer indexes, instead of strings like '[0]'. This logic replaces\n                # those, allowing inspected_keys in checks to use the same syntax.\n                for i in range(0, len(match)):\n                    if type(match[i]) == int:\n                        match[i] = f\"[{match[i]}]\"\n\n                if match[:-1] == path_elements:\n                    # Inspected key exists\n                    value = match[-1]\n                    if ANY_VALUE in expected_values and value is not None and (not isinstance(value, str) or value):\n                        # Key is found on the configuration - if it accepts any value, the check is PASSED\n                        return CheckResult.PASSED\n                    if isinstance(value, list) and len(value) == 1:\n                        value = value[0]\n                    if self._is_variable_dependant(value):\n                        # If the tested attribute is variable-dependant, then result is PASSED\n                        return CheckResult.PASSED\n                    if value in expected_values:\n                        return CheckResult.PASSED\n\n                    # handle boolean case sensitivity (e.g., CFN accepts the string \"true\" as a boolean)\n                    if isinstance(value, str) and value.lower() in ('true', 'false'):\n                        value = value.lower() == 'true'\n                        if value in expected_values:\n                            return CheckResult.PASSED\n                    return CheckResult.FAILED\n\n        return self.missing_block_result\n\n    @abstractmethod\n    def get_inspected_key(self) -> str:\n        \"\"\"\n        :return: JSONPath syntax path of the checked attribute\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_expected_values(self) -> List[Any]:\n        \"\"\"\n        Override the method with the list of acceptable values if the check has more than one possible expected value, given\n        the inspected key\n        :return: List of expected values, defaults to a list of the expected value\n        \"\"\"\n        return [self.get_expected_value()]\n\n    def get_expected_value(self) -> Any:\n        \"\"\"\n        Returns the default expected value, governed by provider best practices\n        \"\"\"\n        return True\n\n    def get_evaluated_keys(self) -> List[str]:\n        return force_list(self.get_inspected_key())\n", "path": "checkov/cloudformation/checks/resource/base_resource_value_check.py"}], "after_files": [{"content": "import re\nfrom abc import abstractmethod\nfrom collections.abc import Iterable\nfrom typing import List, Any, Dict\n\nfrom checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck\nfrom checkov.cloudformation.context_parser import ContextParser\nfrom checkov.common.parsers.node import StrNode, DictNode\nfrom checkov.common.models.consts import ANY_VALUE\nfrom checkov.common.models.enums import CheckResult, CheckCategories\nfrom checkov.common.util.type_forcers import force_list\nfrom checkov.common.util.var_utils import is_cloudformation_variable_dependent\n\nVARIABLE_DEPENDANT_REGEX = re.compile(r\"(?:Ref)\\.[^\\s]+\")\n\n\nclass BaseResourceValueCheck(BaseResourceCheck):\n    def __init__(\n        self,\n        name: str,\n        id: str,\n        categories: \"Iterable[CheckCategories]\",\n        supported_resources: \"Iterable[str]\",\n        missing_block_result: CheckResult = CheckResult.FAILED,\n    ) -> None:\n        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)\n        self.missing_block_result = missing_block_result\n\n    @staticmethod\n    def _filter_key_path(path: str) -> List[str]:\n        \"\"\"\n        Filter an attribute path to contain only named attributes by dropping array indices from the path)\n        :param path: valid JSONPath of an attribute\n        :return: List of named attributes with respect to the input JSONPath order\n        \"\"\"\n        regex = re.compile(r\"^\\[?\\d+\\]?$\")\n        return [x for x in path.split(\"/\") if not re.search(regex, x)]\n\n    @staticmethod\n    def _is_variable_dependant(value: Any) -> bool:\n        return is_cloudformation_variable_dependent(value)\n\n    @staticmethod\n    def _is_nesting_key(inspected_attributes: List[str], key: str) -> bool:\n        \"\"\"\n        Resolves whether a key is a subset of the inspected nesting attributes\n        :param inspected_attributes: list of nesting attributes\n        :param key: JSONPath key of an attribute\n        :return: True/False\n        \"\"\"\n        return any(x in key for x in inspected_attributes)\n\n    def scan_resource_conf(self, conf: Dict[StrNode, DictNode]) -> CheckResult:\n        inspected_key = self.get_inspected_key()\n        expected_values = self.get_expected_values()\n        path_elements = inspected_key.split(\"/\")\n        matches = ContextParser.search_deep_keys(path_elements[-1], conf, [])\n        if len(matches) > 0:\n            for match in matches:\n                # CFN files are parsed differently from terraform, which causes the path search above to behave differently.\n                # The tesult is path parts with integer indexes, instead of strings like '[0]'. This logic replaces\n                # those, allowing inspected_keys in checks to use the same syntax.\n                # The last value shouldn't be changed, because it could be indeed a valid number\n                for i in range(0, len(match) - 1):\n                    if type(match[i]) == int:\n                        match[i] = f\"[{match[i]}]\"\n\n                if match[:-1] == path_elements:\n                    # Inspected key exists\n                    value = match[-1]\n                    if ANY_VALUE in expected_values and value is not None and (not isinstance(value, str) or value):\n                        # Key is found on the configuration - if it accepts any value, the check is PASSED\n                        return CheckResult.PASSED\n                    if isinstance(value, list) and len(value) == 1:\n                        value = value[0]\n                    if self._is_variable_dependant(value):\n                        # If the tested attribute is variable-dependant, then result is PASSED\n                        return CheckResult.PASSED\n                    if value in expected_values:\n                        return CheckResult.PASSED\n\n                    # handle boolean case sensitivity (e.g., CFN accepts the string \"true\" as a boolean)\n                    if isinstance(value, str) and value.lower() in ('true', 'false'):\n                        value = value.lower() == 'true'\n                        if value in expected_values:\n                            return CheckResult.PASSED\n                    return CheckResult.FAILED\n\n        return self.missing_block_result\n\n    @abstractmethod\n    def get_inspected_key(self) -> str:\n        \"\"\"\n        :return: JSONPath syntax path of the checked attribute\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_expected_values(self) -> List[Any]:\n        \"\"\"\n        Override the method with the list of acceptable values if the check has more than one possible expected value, given\n        the inspected key\n        :return: List of expected values, defaults to a list of the expected value\n        \"\"\"\n        return [self.get_expected_value()]\n\n    def get_expected_value(self) -> Any:\n        \"\"\"\n        Returns the default expected value, governed by provider best practices\n        \"\"\"\n        return True\n\n    def get_evaluated_keys(self) -> List[str]:\n        return force_list(self.get_inspected_key())\n", "path": "checkov/cloudformation/checks/resource/base_resource_value_check.py"}]}