We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
False positive for CKV_AWS_46: "Ensure no hard coded AWS access key and secret key exists in EC2 user data" 1
The [`string_has_secrets`](https://github.com/bridgecrewio/checkov/blob/master/checkov/common/util/secrets.py) function returns `True` when passed any SHA1 hash. This is problematic because with Terraform resources similar to:

```
resource "aws_instance" "test" {
   // ...
   user_data = filebase64("provision.sh")
}
```

The plan is generated using the hash of the user data, e.g.:

```
10:28:13  #16 29.02       + user_data                    = "d1b0706c4879b31a195d01f3a967e8b35d95cbb7"
```

... which `string_has_secrets` considers as a secret. My suggest would be to have the function return `False` if the user_data is _only_ a SHA1 or MD5 hash

--- 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/common/util/secrets.py`
Content:
```
1 import itertools
2 import re
3 
4 # secret categories for use as constants
5 AWS = 'aws'
6 AZURE = 'azure'
7 GCP = 'gcp'
8 GENERAL = 'general'
9 ALL = 'all'
10 
11 # Taken from various git-secrets forks that add Azure and GCP support to base AWS.
12 # The groups here are the result of running git secrets --register-[aws|azure|gcp]
13 # https://github.com/awslabs/git-secrets
14 # https://github.com/deshpandetanmay/git-secrets
15 # https://github.com/msalemcode/git-secrets#options-for-register-azure
16 _secrets_regexes = {
17     'azure': [
18         r'''("|')?[A-Z0-9a-z!"\#$%&'()*+,\-./:;<=>?@\[\\\]^_‘{|}~]{32}("|')?$''',
19         r'''("|')?[A-Z0-9a-z!"\#$%&'()*+,\-./:;<=>?@\[\\\]^_‘{|}~]{88}("|')?$''',
20         "(\"|')?[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}(\"|')?",
21         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][o|O][n|N][m|M][i|I][c|C][r|R][o|O][s|S][o|O][f|F][t|T][.][c|C][o|O][m|M](\"|')?",
22         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][b|B][l|L][o|O][b|B][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\"|')?",
23         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][q|Q][u|U][e|E][u|U][e|E][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\"|')?",
24         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][t|T][a|A][b|B][l|L][e|E][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\"|')?",
25         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][d|D][a|A][t|T][a|A][b|B][a|A][s|S][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\"|')?",
26         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][s|S][e|E][r|R][v|V][i|I][c|C][e|E][b|B][u|U][s|S][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\"|')?",
27         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][t|T][i|I][m|M][e|E][s|S][e|E][r|R][i|I][e|E][s|S][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\"|')?",
28         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][a|T][c|C][c|C][e|E][s|S][s|S][c|C][o|O][n|N][t|T][r|R][o|O][l|L][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\"|')?",
29         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][a|A][z|Z][u|U][r|R][e|E][h|H][d|D][i|I][n|N][s|S][i|I][g|G][h|H][t|T][.][n|N][e|E][t|T](\"|')?",
30         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][c|C][l|L][o|O][u|U][d|D][a|A][p|P][p|P][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\"|')?",
31         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][c|C][l|L][o|O][u|U][d|D][a|A][p|P][p|P][.][n|N][e|E][t|T](\"|')?",
32         "(\"|')?.*[0-9a-zA-Z]{2,256}[.][d|D][o|O][c|C][u|U][m|M][e|E][n|N][t|T][s|S][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\"|')?",
33     ],
34 
35     'aws': [
36         "(?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=])",  # AWS secret access key
37         "(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}",  # AWS access key ID
38         "(\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(\"|')?\\s*(:|=>|=)\\s*(\"|')?[A-Za-z0-9/\\+=]{40}(\"|')?",
39         "(\"|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?(\"|')?\\s*(:|=>|=)\\s*(\"|')?[0-9]{4}\\-?[0-9]{4}\\-?[0-9]{4}(\"|')?"
40     ],
41 
42     'gcp': [
43         "\bprivate_key.*\b"
44     ],
45 
46     'general': [
47         "^-----BEGIN (RSA|EC|DSA|GPP) PRIVATE KEY-----$",
48     ]
49 }
50 
51 # first compile each unique regex while maintaining the mapping
52 _patterns = {k: [re.compile(p, re.DOTALL) for p in v] for k, v in _secrets_regexes.items()}
53 
54 # now combine all the compiled patterns into one long list
55 _patterns['all'] = list(itertools.chain.from_iterable(_patterns.values()))
56 
57 
58 def string_has_secrets(s: str, *categories) -> bool:
59     """
60     Check whether the specified string has any matches for the regexes in the specified category(ies).
61 
62     If categories is blank, then this method checks all categories. It is recommended to use the category constants
63     provided.
64 
65     Examples:
66     string_has_secrets(some_string) -> checks all regexes
67     string_has_secrets(some_string, AWS, GENERAL) -> checks only AWS and general regexes.
68 
69     :param s:
70     :param categories:
71     :return:
72     """
73 
74     # set a default if no category is provided; or, if categories were provided and they include 'all', then just set it
75     # explicitly so we don't do any duplication
76     if not categories or 'all' in categories:
77         categories = ['all']
78 
79     for c in categories:
80         if any([pattern.search(s) for pattern in _patterns[c]]):
81             return True
82     return False
83
```
--- 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/common/util/secrets.py b/checkov/common/util/secrets.py
--- a/checkov/common/util/secrets.py
+++ b/checkov/common/util/secrets.py
@@ -54,6 +54,16 @@
 # now combine all the compiled patterns into one long list
 _patterns['all'] = list(itertools.chain.from_iterable(_patterns.values()))
 
+_hash_patterns = list(map(lambda regex: re.compile(regex, re.IGNORECASE), ['^[a-f0-9]{32}$', '^[a-f0-9]{40}$']))
+def is_hash(s: str) -> bool:
+    """
+    Checks whether a string is a MD5 or SHA1 hash
+
+    :param s:
+    :return:
+    """
+    return any([pattern.search(s) for pattern in _hash_patterns])
+
 
 def string_has_secrets(s: str, *categories) -> bool:
     """
@@ -76,6 +86,9 @@
     if not categories or 'all' in categories:
         categories = ['all']
 
+    if is_hash(s):
+        return False
+
     for c in categories:
         if any([pattern.search(s) for pattern in _patterns[c]]):
             return True

{"golden_diff": "diff --git a/checkov/common/util/secrets.py b/checkov/common/util/secrets.py\n--- a/checkov/common/util/secrets.py\n+++ b/checkov/common/util/secrets.py\n@@ -54,6 +54,16 @@\n # now combine all the compiled patterns into one long list\n _patterns['all'] = list(itertools.chain.from_iterable(_patterns.values()))\n \n+_hash_patterns = list(map(lambda regex: re.compile(regex, re.IGNORECASE), ['^[a-f0-9]{32}$', '^[a-f0-9]{40}$']))\n+def is_hash(s: str) -> bool:\n+    \"\"\"\n+    Checks whether a string is a MD5 or SHA1 hash\n+\n+    :param s:\n+    :return:\n+    \"\"\"\n+    return any([pattern.search(s) for pattern in _hash_patterns])\n+\n \n def string_has_secrets(s: str, *categories) -> bool:\n     \"\"\"\n@@ -76,6 +86,9 @@\n     if not categories or 'all' in categories:\n         categories = ['all']\n \n+    if is_hash(s):\n+        return False\n+\n     for c in categories:\n         if any([pattern.search(s) for pattern in _patterns[c]]):\n             return True\n", "issue": "False positive for CKV_AWS_46: \"Ensure no hard coded AWS access key and secret key exists in EC2 user data\" 1\nThe [`string_has_secrets`](https://github.com/bridgecrewio/checkov/blob/master/checkov/common/util/secrets.py) function returns `True` when passed any SHA1 hash. This is problematic because with Terraform resources similar to:\r\n\r\n```\r\nresource \"aws_instance\" \"test\" {\r\n   // ...\r\n   user_data = filebase64(\"provision.sh\")\r\n}\r\n```\r\n\r\nThe plan is generated using the hash of the user data, e.g.:\r\n\r\n```\r\n10:28:13  #16 29.02       + user_data                    = \"d1b0706c4879b31a195d01f3a967e8b35d95cbb7\"\r\n```\r\n\r\n... which `string_has_secrets` considers as a secret. My suggest would be to have the function return `False` if the user_data is _only_ a SHA1 or MD5 hash\n", "before_files": [{"content": "import itertools\nimport re\n\n# secret categories for use as constants\nAWS = 'aws'\nAZURE = 'azure'\nGCP = 'gcp'\nGENERAL = 'general'\nALL = 'all'\n\n# Taken from various git-secrets forks that add Azure and GCP support to base AWS.\n# The groups here are the result of running git secrets --register-[aws|azure|gcp]\n# https://github.com/awslabs/git-secrets\n# https://github.com/deshpandetanmay/git-secrets\n# https://github.com/msalemcode/git-secrets#options-for-register-azure\n_secrets_regexes = {\n    'azure': [\n        r'''(\"|')?[A-Z0-9a-z!\"\\#$%&'()*+,\\-./:;<=>?@\\[\\\\\\]^_\u2018{|}~]{32}(\"|')?$''',\n        r'''(\"|')?[A-Z0-9a-z!\"\\#$%&'()*+,\\-./:;<=>?@\\[\\\\\\]^_\u2018{|}~]{88}(\"|')?$''',\n        \"(\\\"|')?[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}(\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][o|O][n|N][m|M][i|I][c|C][r|R][o|O][s|S][o|O][f|F][t|T][.][c|C][o|O][m|M](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][b|B][l|L][o|O][b|B][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][q|Q][u|U][e|E][u|U][e|E][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][t|T][a|A][b|B][l|L][e|E][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][d|D][a|A][t|T][a|A][b|B][a|A][s|S][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][s|S][e|E][r|R][v|V][i|I][c|C][e|E][b|B][u|U][s|S][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][t|T][i|I][m|M][e|E][s|S][e|E][r|R][i|I][e|E][s|S][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][a|T][c|C][c|C][e|E][s|S][s|S][c|C][o|O][n|N][t|T][r|R][o|O][l|L][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][a|A][z|Z][u|U][r|R][e|E][h|H][d|D][i|I][n|N][s|S][i|I][g|G][h|H][t|T][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][c|C][l|L][o|O][u|U][d|D][a|A][p|P][p|P][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][c|C][l|L][o|O][u|U][d|D][a|A][p|P][p|P][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][d|D][o|O][c|C][u|U][m|M][e|E][n|N][t|T][s|S][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\\\"|')?\",\n    ],\n\n    'aws': [\n        \"(?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=])\",  # AWS secret access key\n        \"(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}\",  # AWS access key ID\n        \"(\\\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(\\\"|')?\\\\s*(:|=>|=)\\\\s*(\\\"|')?[A-Za-z0-9/\\\\+=]{40}(\\\"|')?\",\n        \"(\\\"|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?(\\\"|')?\\\\s*(:|=>|=)\\\\s*(\\\"|')?[0-9]{4}\\\\-?[0-9]{4}\\\\-?[0-9]{4}(\\\"|')?\"\n    ],\n\n    'gcp': [\n        \"\\bprivate_key.*\\b\"\n    ],\n\n    'general': [\n        \"^-----BEGIN (RSA|EC|DSA|GPP) PRIVATE KEY-----$\",\n    ]\n}\n\n# first compile each unique regex while maintaining the mapping\n_patterns = {k: [re.compile(p, re.DOTALL) for p in v] for k, v in _secrets_regexes.items()}\n\n# now combine all the compiled patterns into one long list\n_patterns['all'] = list(itertools.chain.from_iterable(_patterns.values()))\n\n\ndef string_has_secrets(s: str, *categories) -> bool:\n    \"\"\"\n    Check whether the specified string has any matches for the regexes in the specified category(ies).\n\n    If categories is blank, then this method checks all categories. It is recommended to use the category constants\n    provided.\n\n    Examples:\n    string_has_secrets(some_string) -> checks all regexes\n    string_has_secrets(some_string, AWS, GENERAL) -> checks only AWS and general regexes.\n\n    :param s:\n    :param categories:\n    :return:\n    \"\"\"\n\n    # set a default if no category is provided; or, if categories were provided and they include 'all', then just set it\n    # explicitly so we don't do any duplication\n    if not categories or 'all' in categories:\n        categories = ['all']\n\n    for c in categories:\n        if any([pattern.search(s) for pattern in _patterns[c]]):\n            return True\n    return False\n", "path": "checkov/common/util/secrets.py"}], "after_files": [{"content": "import itertools\nimport re\n\n# secret categories for use as constants\nAWS = 'aws'\nAZURE = 'azure'\nGCP = 'gcp'\nGENERAL = 'general'\nALL = 'all'\n\n# Taken from various git-secrets forks that add Azure and GCP support to base AWS.\n# The groups here are the result of running git secrets --register-[aws|azure|gcp]\n# https://github.com/awslabs/git-secrets\n# https://github.com/deshpandetanmay/git-secrets\n# https://github.com/msalemcode/git-secrets#options-for-register-azure\n_secrets_regexes = {\n    'azure': [\n        r'''(\"|')?[A-Z0-9a-z!\"\\#$%&'()*+,\\-./:;<=>?@\\[\\\\\\]^_\u2018{|}~]{32}(\"|')?$''',\n        r'''(\"|')?[A-Z0-9a-z!\"\\#$%&'()*+,\\-./:;<=>?@\\[\\\\\\]^_\u2018{|}~]{88}(\"|')?$''',\n        \"(\\\"|')?[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}(\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][o|O][n|N][m|M][i|I][c|C][r|R][o|O][s|S][o|O][f|F][t|T][.][c|C][o|O][m|M](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][b|B][l|L][o|O][b|B][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][q|Q][u|U][e|E][u|U][e|E][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][t|T][a|A][b|B][l|L][e|E][.][c|C][o|O][r|R][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][d|D][a|A][t|T][a|A][b|B][a|A][s|S][e|E][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][s|S][e|E][r|R][v|V][i|I][c|C][e|E][b|B][u|U][s|S][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][t|T][i|I][m|M][e|E][s|S][e|E][r|R][i|I][e|E][s|S][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][a|T][c|C][c|C][e|E][s|S][s|S][c|C][o|O][n|N][t|T][r|R][o|O][l|L][.][w|W][i|I][n|N][d|D][o|O][w|W][s|S][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][a|A][z|Z][u|U][r|R][e|E][h|H][d|D][i|I][n|N][s|S][i|I][g|G][h|H][t|T][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][c|C][l|L][o|O][u|U][d|D][a|A][p|P][p|P][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][c|C][l|L][o|O][u|U][d|D][a|A][p|P][p|P][.][n|N][e|E][t|T](\\\"|')?\",\n        \"(\\\"|')?.*[0-9a-zA-Z]{2,256}[.][d|D][o|O][c|C][u|U][m|M][e|E][n|N][t|T][s|S][.][a|A][z|Z][u|U][r|R][e|E][.][c|C][o|O][m|M](\\\"|')?\",\n    ],\n\n    'aws': [\n        \"(?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=])\",  # AWS secret access key\n        \"(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}\",  # AWS access key ID\n        \"(\\\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(\\\"|')?\\\\s*(:|=>|=)\\\\s*(\\\"|')?[A-Za-z0-9/\\\\+=]{40}(\\\"|')?\",\n        \"(\\\"|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?(\\\"|')?\\\\s*(:|=>|=)\\\\s*(\\\"|')?[0-9]{4}\\\\-?[0-9]{4}\\\\-?[0-9]{4}(\\\"|')?\"\n    ],\n\n    'gcp': [\n        \"\\bprivate_key.*\\b\"\n    ],\n\n    'general': [\n        \"^-----BEGIN (RSA|EC|DSA|GPP) PRIVATE KEY-----$\",\n    ]\n}\n\n# first compile each unique regex while maintaining the mapping\n_patterns = {k: [re.compile(p, re.DOTALL) for p in v] for k, v in _secrets_regexes.items()}\n\n# now combine all the compiled patterns into one long list\n_patterns['all'] = list(itertools.chain.from_iterable(_patterns.values()))\n\n_hash_patterns = list(map(lambda regex: re.compile(regex, re.IGNORECASE), ['^[a-f0-9]{32}$', '^[a-f0-9]{40}$']))\ndef is_hash(s: str) -> bool:\n    \"\"\"\n    Checks whether a string is a MD5 or SHA1 hash\n\n    :param s:\n    :return:\n    \"\"\"\n    return any([pattern.search(s) for pattern in _hash_patterns])\n\n\ndef string_has_secrets(s: str, *categories) -> bool:\n    \"\"\"\n    Check whether the specified string has any matches for the regexes in the specified category(ies).\n\n    If categories is blank, then this method checks all categories. It is recommended to use the category constants\n    provided.\n\n    Examples:\n    string_has_secrets(some_string) -> checks all regexes\n    string_has_secrets(some_string, AWS, GENERAL) -> checks only AWS and general regexes.\n\n    :param s:\n    :param categories:\n    :return:\n    \"\"\"\n\n    # set a default if no category is provided; or, if categories were provided and they include 'all', then just set it\n    # explicitly so we don't do any duplication\n    if not categories or 'all' in categories:\n        categories = ['all']\n\n    if is_hash(s):\n        return False\n\n    for c in categories:\n        if any([pattern.search(s) for pattern in _patterns[c]]):\n            return True\n    return False\n", "path": "checkov/common/util/secrets.py"}]}