prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  CloudFormation EC2Credentials.py does evaluate if the UserData is base64 encoded
  **Describe the issue**
  The check EC2Credentials.py which checks the UserData of a CloudFormation template against secrets does not work if the userdata are already encoded in base64. 
  The check is not returning the correct result and the processing time is very slow.
  
  **Examples**
  ```yaml
  AWSTemplateFormatVersion: "2010-09-09"
  Resources:
    Resource0:
      Type: AWS::EC2::Instance
      Properties:
        ImageId: ami-04169656fea786776
        UserData: IyEgL2Jpbi9iYXNoCnN1ZG8gYXB0LWdldCB1cGRhdGUKc3VkbyBhcHQtZ2V0IGluc3RhbGwgLXkgYXBhY2hlMgpzdWRvIHN5c3RlbWN0bCBzdGFydCBhcGFjaGUyCnN1ZG8gc3lzdGVtY3RsIGVuYWJsZSBhcGFjaGUyCmV4cG9ydCBBV1NfQUNDRVNTX0tFWV9JRApleHBvcnQgQVdTX0FDQ0VTU19LRVlfSUQ9QUtJQUlPU0ZPRE5ON0VYQU1QTEUKZXhwb3J0IEFXU19TRUNSRVRfQUNDRVNTX0tFWT13SmFsclhVdG5GRU1JL0s3TURFTkcvYlB4UmZpQ1lFWEFNUExFS0VZCmV4cG9ydCBBV1NfREVGQVVMVF9SRUdJT049dXMtd2VzdC0yCmVjaG8gIjxoMT5EZXBsb3llZCB2aWEgVGVycmFmb3JtPC9oMT4iIHwgc3VkbyB0ZWUgL3Zhci93d3cvaHRtbC9pbmRleC5odG1s
  
  ```
  
  **Version (please complete the following information):**
   - Checkov Version [e.g. 22]
   - >2.0.0
  
  **Additional context**
  Fix implemented here by trying to decode the base64 string.
  https://github.com/j2clerck/checkov/commit/af9abd724520ec21ec5510dfc5db2ef83fd9e6dc
  
  
  --- 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/aws/EC2Credentials.py`
  Content:
  ```
  1 from typing import List
  2 
  3 from checkov.common.models.enums import CheckResult, CheckCategories
  4 from checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck
  5 from checkov.common.util.secrets import get_secrets_from_string
  6 
  7 
  8 class EC2Credentials(BaseResourceCheck):
  9     def __init__(self):
  10         name = "Ensure no hard-coded secrets exist in EC2 user data"
  11         id = "CKV_AWS_46"
  12         supported_resources = ['AWS::EC2::Instance']
  13         categories = [CheckCategories.SECRETS]
  14         super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
  15 
  16     def scan_resource_conf(self, conf):
  17         if 'Properties' in conf.keys():
  18             if 'UserData' in conf['Properties'].keys():
  19                 user_data = conf['Properties']['UserData']
  20                 # Cast to string as user data object can look slightly different depending
  21                 # on Yaml or JSON CF Templates and how the B64 conversion is done.
  22                 user_data_str = str(user_data)
  23                 if isinstance(user_data_str, str):
  24                     secrets = get_secrets_from_string(str(user_data_str))
  25                     if secrets:
  26                         for idx, secret in enumerate(secrets):
  27                             conf[f'{self.id}_secret_{idx}'] = secret
  28                         return CheckResult.FAILED
  29         return CheckResult.PASSED
  30 
  31     def get_evaluated_keys(self) -> List[str]:
  32         return ["Properties/UserData"]
  33 
  34 
  35 check = EC2Credentials()
  36
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/checkov/cloudformation/checks/resource/aws/EC2Credentials.py b/checkov/cloudformation/checks/resource/aws/EC2Credentials.py
  --- a/checkov/cloudformation/checks/resource/aws/EC2Credentials.py
  +++ b/checkov/cloudformation/checks/resource/aws/EC2Credentials.py
  @@ -1,4 +1,5 @@
   from typing import List
  +from base64 import b64decode
   
   from checkov.common.models.enums import CheckResult, CheckCategories
   from checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck
  @@ -17,9 +18,15 @@
           if 'Properties' in conf.keys():
               if 'UserData' in conf['Properties'].keys():
                   user_data = conf['Properties']['UserData']
  -                # Cast to string as user data object can look slightly different depending
  -                # on Yaml or JSON CF Templates and how the B64 conversion is done.
  -                user_data_str = str(user_data)
  +                # In some case, the UserData might be a base64 encoded string which will slow down (3 minutes)
  +                # the get_secrets_from_string function.
  +                try:
  +                    user_data_str = b64decode(user_data).decode()
  +                except Exception:
  +                    # Cast to string as user data object can look slightly different depending
  +                    # on Yaml or JSON CF Templates and how the B64 conversion is done.
  +                    user_data_str = str(user_data)
  +
                   if isinstance(user_data_str, str):
                       secrets = get_secrets_from_string(str(user_data_str))
                       if secrets:
  
verification_info: {"golden_diff": "diff --git a/checkov/cloudformation/checks/resource/aws/EC2Credentials.py b/checkov/cloudformation/checks/resource/aws/EC2Credentials.py\n--- a/checkov/cloudformation/checks/resource/aws/EC2Credentials.py\n+++ b/checkov/cloudformation/checks/resource/aws/EC2Credentials.py\n@@ -1,4 +1,5 @@\n from typing import List\n+from base64 import b64decode\n \n from checkov.common.models.enums import CheckResult, CheckCategories\n from checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck\n@@ -17,9 +18,15 @@\n         if 'Properties' in conf.keys():\n             if 'UserData' in conf['Properties'].keys():\n                 user_data = conf['Properties']['UserData']\n-                # Cast to string as user data object can look slightly different depending\n-                # on Yaml or JSON CF Templates and how the B64 conversion is done.\n-                user_data_str = str(user_data)\n+                # In some case, the UserData might be a base64 encoded string which will slow down (3 minutes)\n+                # the get_secrets_from_string function.\n+                try:\n+                    user_data_str = b64decode(user_data).decode()\n+                except Exception:\n+                    # Cast to string as user data object can look slightly different depending\n+                    # on Yaml or JSON CF Templates and how the B64 conversion is done.\n+                    user_data_str = str(user_data)\n+\n                 if isinstance(user_data_str, str):\n                     secrets = get_secrets_from_string(str(user_data_str))\n                     if secrets:\n", "issue": "CloudFormation EC2Credentials.py does evaluate if the UserData is base64 encoded\n**Describe the issue**\r\nThe check EC2Credentials.py which checks the UserData of a CloudFormation template against secrets does not work if the userdata are already encoded in base64. \r\nThe check is not returning the correct result and the processing time is very slow.\r\n\r\n**Examples**\r\n```yaml\r\nAWSTemplateFormatVersion: \"2010-09-09\"\r\nResources:\r\n  Resource0:\r\n    Type: AWS::EC2::Instance\r\n    Properties:\r\n      ImageId: ami-04169656fea786776\r\n      UserData: IyEgL2Jpbi9iYXNoCnN1ZG8gYXB0LWdldCB1cGRhdGUKc3VkbyBhcHQtZ2V0IGluc3RhbGwgLXkgYXBhY2hlMgpzdWRvIHN5c3RlbWN0bCBzdGFydCBhcGFjaGUyCnN1ZG8gc3lzdGVtY3RsIGVuYWJsZSBhcGFjaGUyCmV4cG9ydCBBV1NfQUNDRVNTX0tFWV9JRApleHBvcnQgQVdTX0FDQ0VTU19LRVlfSUQ9QUtJQUlPU0ZPRE5ON0VYQU1QTEUKZXhwb3J0IEFXU19TRUNSRVRfQUNDRVNTX0tFWT13SmFsclhVdG5GRU1JL0s3TURFTkcvYlB4UmZpQ1lFWEFNUExFS0VZCmV4cG9ydCBBV1NfREVGQVVMVF9SRUdJT049dXMtd2VzdC0yCmVjaG8gIjxoMT5EZXBsb3llZCB2aWEgVGVycmFmb3JtPC9oMT4iIHwgc3VkbyB0ZWUgL3Zhci93d3cvaHRtbC9pbmRleC5odG1s\r\n\r\n```\r\n\r\n**Version (please complete the following information):**\r\n - Checkov Version [e.g. 22]\r\n - >2.0.0\r\n\r\n**Additional context**\r\nFix implemented here by trying to decode the base64 string.\r\nhttps://github.com/j2clerck/checkov/commit/af9abd724520ec21ec5510dfc5db2ef83fd9e6dc\r\n\n", "before_files": [{"content": "from typing import List\n\nfrom checkov.common.models.enums import CheckResult, CheckCategories\nfrom checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck\nfrom checkov.common.util.secrets import get_secrets_from_string\n\n\nclass EC2Credentials(BaseResourceCheck):\n    def __init__(self):\n        name = \"Ensure no hard-coded secrets exist in EC2 user data\"\n        id = \"CKV_AWS_46\"\n        supported_resources = ['AWS::EC2::Instance']\n        categories = [CheckCategories.SECRETS]\n        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)\n\n    def scan_resource_conf(self, conf):\n        if 'Properties' in conf.keys():\n            if 'UserData' in conf['Properties'].keys():\n                user_data = conf['Properties']['UserData']\n                # Cast to string as user data object can look slightly different depending\n                # on Yaml or JSON CF Templates and how the B64 conversion is done.\n                user_data_str = str(user_data)\n                if isinstance(user_data_str, str):\n                    secrets = get_secrets_from_string(str(user_data_str))\n                    if secrets:\n                        for idx, secret in enumerate(secrets):\n                            conf[f'{self.id}_secret_{idx}'] = secret\n                        return CheckResult.FAILED\n        return CheckResult.PASSED\n\n    def get_evaluated_keys(self) -> List[str]:\n        return [\"Properties/UserData\"]\n\n\ncheck = EC2Credentials()\n", "path": "checkov/cloudformation/checks/resource/aws/EC2Credentials.py"}], "after_files": [{"content": "from typing import List\nfrom base64 import b64decode\n\nfrom checkov.common.models.enums import CheckResult, CheckCategories\nfrom checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck\nfrom checkov.common.util.secrets import get_secrets_from_string\n\n\nclass EC2Credentials(BaseResourceCheck):\n    def __init__(self):\n        name = \"Ensure no hard-coded secrets exist in EC2 user data\"\n        id = \"CKV_AWS_46\"\n        supported_resources = ['AWS::EC2::Instance']\n        categories = [CheckCategories.SECRETS]\n        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)\n\n    def scan_resource_conf(self, conf):\n        if 'Properties' in conf.keys():\n            if 'UserData' in conf['Properties'].keys():\n                user_data = conf['Properties']['UserData']\n                # In some case, the UserData might be a base64 encoded string which will slow down (3 minutes)\n                # the get_secrets_from_string function.\n                try:\n                    user_data_str = b64decode(user_data).decode()\n                except Exception:\n                    # Cast to string as user data object can look slightly different depending\n                    # on Yaml or JSON CF Templates and how the B64 conversion is done.\n                    user_data_str = str(user_data)\n\n                if isinstance(user_data_str, str):\n                    secrets = get_secrets_from_string(str(user_data_str))\n                    if secrets:\n                        for idx, secret in enumerate(secrets):\n                            conf[f'{self.id}_secret_{idx}'] = secret\n                        return CheckResult.FAILED\n        return CheckResult.PASSED\n\n    def get_evaluated_keys(self) -> List[str]:\n        return [\"Properties/UserData\"]\n\n\ncheck = EC2Credentials()\n", "path": "checkov/cloudformation/checks/resource/aws/EC2Credentials.py"}]}