We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Terraform azurerm_windows_function_app  resource - CKV_SECRET_6 false positive for active_directory_v2 setting
**Describe the issue**
When adding azure function app with identity provider active directory v2, checkov reports false positive
secret is not exposed but checkov reports :

|  0 | CKV_SECRET_6 | xxxxxxxxx| 0a69b97b56bf2230f607111888418a59f1891c92 | Base64 High Entropy String | https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/secrets-policies/secrets-policy-index/git-secrets-6.html |

with resource 0a69b97b56bf2230f607111888418a59f1891c92

Because from resource id is not clear which resource is the culprit the only possible one is client_secret_setting_name  which is set to 
"MICROSOFT_PROVIDER_AUTHENTICATION_SECRET" and not exposed secret. 
**Examples**

snippet of resource azurerm_windows_function_app :

    active_directory_v2 {
      client_id                   = local.managed_identity_client_id
      client_secret_setting_name  = "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET"
      tenant_auth_endpoint        = local.identity_provider.tenant_auth_endpoint
      www_authentication_disabled = false
    }

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

**Additional context**
Add any other context about the problem here.


--- 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/secrets/plugins/detector_utils.py`
Content:
```
1 from __future__ import annotations
2 
3 import json
4 import re
5 from re import Pattern
6 from typing import Any, TYPE_CHECKING, Optional
7 
8 from detect_secrets.util.filetype import FileType
9 from detect_secrets.plugins.keyword import DENYLIST
10 from detect_secrets.plugins.keyword import AFFIX_REGEX
11 from detect_secrets.plugins.keyword import CLOSING
12 from detect_secrets.plugins.keyword import OPTIONAL_WHITESPACE
13 from detect_secrets.plugins.keyword import QUOTE
14 from detect_secrets.plugins.keyword import SECRET
15 
16 from checkov.secrets.parsers.terraform.multiline_parser import terraform_multiline_parser
17 from checkov.secrets.parsers.terraform.single_line_parser import terraform_single_line_parser
18 from checkov.secrets.parsers.yaml.multiline_parser import yml_multiline_parser
19 from checkov.secrets.parsers.json.multiline_parser import json_multiline_parser
20 
21 if TYPE_CHECKING:
22     from checkov.secrets.parsers.multiline_parser import BaseMultiLineParser
23     from detect_secrets.core.potential_secret import PotentialSecret
24     from detect_secrets.util.code_snippet import CodeSnippet
25     from detect_secrets.plugins.base import BasePlugin
26 
27 MAX_KEYWORD_LIMIT = 500
28 
29 DENY_LIST_REGEX = r'|'.join(DENYLIST)
30 # Support for suffix after keyword i.e. password_secure = "value"
31 DENY_LIST_REGEX2 = r'({denylist}){suffix}'.format(
32     denylist=DENY_LIST_REGEX,
33     suffix=AFFIX_REGEX,
34 )
35 
36 KEY = r'{words}({closing})?'.format(
37     words=AFFIX_REGEX,
38     closing=CLOSING,
39 )
40 
41 FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX = re.compile(
42     # e.g. var: MY_PASSWORD_123
43     r'{whitespace}({key})?:{whitespace}({quote}?){words}{denylist}({closing})?(\3)'.format(
44         key=KEY,
45         whitespace=OPTIONAL_WHITESPACE,
46         quote=QUOTE,
47         words=AFFIX_REGEX,
48         denylist=DENY_LIST_REGEX2,
49         closing=CLOSING,
50     ),
51     flags=re.IGNORECASE,
52 )
53 
54 QUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX = re.compile(
55     # e.g. var: MY_PASSWORD_123
56     r'{whitespace}"({key})?":{whitespace}("?){words}{denylist}({closing})?(\3)'.format(
57         key=KEY,
58         whitespace=OPTIONAL_WHITESPACE,
59         words=AFFIX_REGEX,
60         denylist=DENY_LIST_REGEX2,
61         closing=CLOSING,
62     ),
63     flags=re.IGNORECASE,
64 )
65 
66 FOLLOWED_BY_COLON_VALUE_SECRET_REGEX = re.compile(
67     # e.g. var: Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==
68     r'{whitespace}({key})?:{whitespace}({quote}?)({secret})(\3)'.format(
69         key=KEY,
70         whitespace=OPTIONAL_WHITESPACE,
71         quote=QUOTE,
72         secret=SECRET,
73     ),
74     flags=re.IGNORECASE,
75 )
76 
77 QUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_SECRET_REGEX = re.compile(
78     # e.g. var: Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==
79     r'{whitespace}"({key})?":{whitespace}("?)({secret})(\3)'.format(
80         key=KEY,
81         whitespace=OPTIONAL_WHITESPACE,
82         secret=SECRET,
83     ),
84     flags=re.IGNORECASE,
85 )
86 
87 FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX = re.compile(
88     # e.g. var = MY_PASSWORD_123
89     r'{whitespace}({key})?={whitespace}({quote}?){words}{denylist}({closing})?(\3)'.format(
90         key=KEY,
91         whitespace=OPTIONAL_WHITESPACE,
92         quote=QUOTE,
93         words=AFFIX_REGEX,
94         denylist=DENY_LIST_REGEX2,
95         closing=CLOSING,
96     ),
97     flags=re.IGNORECASE,
98 )
99 
100 FOLLOWED_BY_EQUAL_VALUE_SECRET_REGEX = re.compile(
101     # e.g. var = Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==
102     r'{whitespace}({key})?={whitespace}({quote}?)({secret})(\3)'.format(
103         key=KEY,
104         whitespace=OPTIONAL_WHITESPACE,
105         quote=QUOTE,
106         secret=SECRET,
107     ),
108     flags=re.IGNORECASE,
109 )
110 
111 ALLOW_LIST = ('secretsmanager', "secretName", "secret_name", "creation_token")  # can add more keys like that
112 ALLOW_LIST_REGEX = r'|'.join(ALLOW_LIST)
113 # Support for suffix of function name i.e "secretsmanager:GetSecretValue"
114 CAMEL_CASE_NAMES = r'[A-Z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*'
115 FUNCTION_CALL_AFTER_KEYWORD_REGEX = re.compile(r'({allowlist})\s*(:|=)\s*{suffix}'.format(
116     allowlist=ALLOW_LIST_REGEX,
117     suffix=AFFIX_REGEX,
118 ))
119 
120 #  if the current regex is not enough, can add more regexes to check
121 
122 YML_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {
123     FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX: 4,
124 }
125 
126 YML_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {
127     FOLLOWED_BY_COLON_VALUE_SECRET_REGEX: 4,
128 }
129 
130 JSON_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {
131     QUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX: 4,
132 }
133 
134 JSON_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {
135     QUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_SECRET_REGEX: 4,
136 }
137 
138 TERRAFORM_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {
139     FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX: 4,
140 }
141 
142 TERRAFORM_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {
143     FOLLOWED_BY_EQUAL_VALUE_SECRET_REGEX: 4,
144 }
145 
146 REGEX_VALUE_KEYWORD_BY_FILETYPE = {
147     FileType.YAML: YML_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,
148     FileType.JSON: JSON_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,
149     FileType.TERRAFORM: TERRAFORM_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,
150 }
151 
152 REGEX_VALUE_SECRET_BY_FILETYPE = {
153     FileType.YAML: YML_PAIR_VALUE_SECRET_REGEX_TO_GROUP,
154     FileType.JSON: JSON_PAIR_VALUE_SECRET_REGEX_TO_GROUP,
155     FileType.TERRAFORM: TERRAFORM_PAIR_VALUE_SECRET_REGEX_TO_GROUP,
156 }
157 
158 SINGLE_LINE_PARSER = {
159     FileType.TERRAFORM: terraform_single_line_parser,
160 }
161 
162 MULTILINE_PARSERS = {
163     FileType.YAML: (
164         (FileType.YAML, yml_multiline_parser),
165     ),
166     FileType.JSON: (
167         (FileType.JSON, json_multiline_parser),
168     ),
169     FileType.TERRAFORM: (
170         (FileType.TERRAFORM, terraform_multiline_parser),
171         (FileType.JSON, json_multiline_parser),
172         (FileType.YAML, yml_multiline_parser),
173     ),
174 }
175 
176 
177 def remove_fp_secrets_in_keys(detected_secrets: set[PotentialSecret], line: str, is_code_file: bool = False) -> None:
178     formatted_line = line.replace('"', '').replace("'", '')
179     secrets_to_remove = set()
180     for detected_secret in detected_secrets:
181         if not detected_secret.secret_value:
182             continue
183         # Found keyword prefix as potential secret
184         if formatted_line.startswith(detected_secret.secret_value):
185             secrets_to_remove.add(detected_secret)
186         # found a function name at the end of the line
187         if formatted_line and FUNCTION_CALL_AFTER_KEYWORD_REGEX.search(formatted_line):
188             secrets_to_remove.add(detected_secret)
189         # secret value is substring of keywork
190         if is_code_file and FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX.search(formatted_line):
191             key, value = line.split("=", 1)
192             if detected_secret.secret_value in key and detected_secret.secret_value in value:
193                 secrets_to_remove.add(detected_secret)
194     detected_secrets -= secrets_to_remove
195 
196 
197 def format_reducing_noise_secret(string: str) -> str:
198     return json.dumps(string)
199 
200 
201 def extract_from_string(pattern: dict[Pattern[str], int] | None, string: str) -> set[str]:
202     matches: set[str] = set()
203     if not pattern:
204         return matches
205     for value_regex, group_number in pattern.items():
206         match = value_regex.search(string)
207         if match:
208             matches |= {match.group(group_number).rstrip('\n')}
209     return matches
210 
211 
212 def detect_secret(
213         scanners: tuple[BasePlugin, ...],
214         filename: str,
215         line: str,
216         line_number: int = 0,
217         is_multiline: Optional[bool] = None,
218         **kwargs: Any,
219 ) -> set[PotentialSecret]:
220     for scanner in scanners:
221         matches = scanner.analyze_line(filename, line, line_number, **kwargs)
222         if matches:
223             if is_multiline:
224                 mark_set_multiline(matches)
225             return matches
226     return set()
227 
228 
229 def analyze_multiline_keyword_combinator(
230         filename: str,
231         scanners: tuple[BasePlugin, ...],
232         multiline_parser: BaseMultiLineParser,
233         line_number: int,
234         context: CodeSnippet | None = None,
235         raw_context: CodeSnippet | None = None,
236         value_pattern: dict[Pattern[str], int] | None = None,
237         secret_pattern: dict[Pattern[str], int] | None = None,
238         is_added: bool = False,
239         is_removed: bool = False,
240         **kwargs: Any,
241 ) -> set[PotentialSecret]:
242     secrets: set[PotentialSecret] = set()
243     if context is None or raw_context is None:
244         return secrets
245     value_secrets = extract_from_string(pattern=secret_pattern, string=context.target_line)
246     for possible_secret in value_secrets:
247         secret_adjust = format_reducing_noise_secret(possible_secret)
248 
249         potential_secrets = detect_secret(
250             scanners=scanners,
251             filename=filename,
252             line=secret_adjust,
253             line_number=line_number,
254             is_added=is_added,
255             is_removed=is_removed,
256             is_multiline=True,  # always true because we check here for multiline
257             kwargs=kwargs
258         )
259 
260         if potential_secrets:
261             possible_keywords: set[str] = set()
262             backwards_range = range(context.target_index - 1, -1, -1)
263             forward_range = range(context.target_index + 1, len(context.lines))
264 
265             possible_keywords |= multiline_parser.get_lines_from_same_object(
266                 search_range=forward_range,
267                 context=context,
268                 raw_context=raw_context,
269                 line_length_limit=MAX_KEYWORD_LIMIT)
270             possible_keywords |= multiline_parser.get_lines_from_same_object(
271                 search_range=backwards_range,
272                 context=context,
273                 raw_context=raw_context,
274                 line_length_limit=MAX_KEYWORD_LIMIT)
275 
276             for other_value in possible_keywords:
277                 if extract_from_string(pattern=value_pattern, string=other_value):
278                     secrets |= potential_secrets
279                     break
280     return secrets
281 
282 
283 def mark_set_multiline(secrets: set[PotentialSecret]) -> None:
284     for sec in secrets:
285         sec.is_multiline = True
286
```
--- 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/secrets/plugins/detector_utils.py b/checkov/secrets/plugins/detector_utils.py
--- a/checkov/secrets/plugins/detector_utils.py
+++ b/checkov/secrets/plugins/detector_utils.py
@@ -108,7 +108,13 @@
     flags=re.IGNORECASE,
 )
 
-ALLOW_LIST = ('secretsmanager', "secretName", "secret_name", "creation_token")  # can add more keys like that
+ALLOW_LIST = (  # can add more keys like that
+    'secretsmanager',
+    "secretName",
+    "secret_name",
+    "creation_token",
+    "client_secret_setting_name",
+)
 ALLOW_LIST_REGEX = r'|'.join(ALLOW_LIST)
 # Support for suffix of function name i.e "secretsmanager:GetSecretValue"
 CAMEL_CASE_NAMES = r'[A-Z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*'

{"golden_diff": "diff --git a/checkov/secrets/plugins/detector_utils.py b/checkov/secrets/plugins/detector_utils.py\n--- a/checkov/secrets/plugins/detector_utils.py\n+++ b/checkov/secrets/plugins/detector_utils.py\n@@ -108,7 +108,13 @@\n     flags=re.IGNORECASE,\n )\n \n-ALLOW_LIST = ('secretsmanager', \"secretName\", \"secret_name\", \"creation_token\")  # can add more keys like that\n+ALLOW_LIST = (  # can add more keys like that\n+    'secretsmanager',\n+    \"secretName\",\n+    \"secret_name\",\n+    \"creation_token\",\n+    \"client_secret_setting_name\",\n+)\n ALLOW_LIST_REGEX = r'|'.join(ALLOW_LIST)\n # Support for suffix of function name i.e \"secretsmanager:GetSecretValue\"\n CAMEL_CASE_NAMES = r'[A-Z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*'\n", "issue": "Terraform azurerm_windows_function_app  resource - CKV_SECRET_6 false positive for active_directory_v2 setting\n**Describe the issue**\r\nWhen adding azure function app with identity provider active directory v2, checkov reports false positive\r\nsecret is not exposed but checkov reports :\r\n\r\n|  0 | CKV_SECRET_6 | xxxxxxxxx| 0a69b97b56bf2230f607111888418a59f1891c92 | Base64 High Entropy String | https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/secrets-policies/secrets-policy-index/git-secrets-6.html |\r\n\r\nwith resource 0a69b97b56bf2230f607111888418a59f1891c92\r\n\r\nBecause from resource id is not clear which resource is the culprit the only possible one is client_secret_setting_name  which is set to \r\n\"MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\" and not exposed secret. \r\n**Examples**\r\n\r\nsnippet of resource azurerm_windows_function_app :\r\n\r\n    active_directory_v2 {\r\n      client_id                   = local.managed_identity_client_id\r\n      client_secret_setting_name  = \"MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\"\r\n      tenant_auth_endpoint        = local.identity_provider.tenant_auth_endpoint\r\n      www_authentication_disabled = false\r\n    }\r\n\r\n**Version (please complete the following information):**\r\n - Checkov Version 2.4.50\r\n\r\n**Additional context**\r\nAdd any other context about the problem here.\r\n\n", "before_files": [{"content": "from __future__ import annotations\n\nimport json\nimport re\nfrom re import Pattern\nfrom typing import Any, TYPE_CHECKING, Optional\n\nfrom detect_secrets.util.filetype import FileType\nfrom detect_secrets.plugins.keyword import DENYLIST\nfrom detect_secrets.plugins.keyword import AFFIX_REGEX\nfrom detect_secrets.plugins.keyword import CLOSING\nfrom detect_secrets.plugins.keyword import OPTIONAL_WHITESPACE\nfrom detect_secrets.plugins.keyword import QUOTE\nfrom detect_secrets.plugins.keyword import SECRET\n\nfrom checkov.secrets.parsers.terraform.multiline_parser import terraform_multiline_parser\nfrom checkov.secrets.parsers.terraform.single_line_parser import terraform_single_line_parser\nfrom checkov.secrets.parsers.yaml.multiline_parser import yml_multiline_parser\nfrom checkov.secrets.parsers.json.multiline_parser import json_multiline_parser\n\nif TYPE_CHECKING:\n    from checkov.secrets.parsers.multiline_parser import BaseMultiLineParser\n    from detect_secrets.core.potential_secret import PotentialSecret\n    from detect_secrets.util.code_snippet import CodeSnippet\n    from detect_secrets.plugins.base import BasePlugin\n\nMAX_KEYWORD_LIMIT = 500\n\nDENY_LIST_REGEX = r'|'.join(DENYLIST)\n# Support for suffix after keyword i.e. password_secure = \"value\"\nDENY_LIST_REGEX2 = r'({denylist}){suffix}'.format(\n    denylist=DENY_LIST_REGEX,\n    suffix=AFFIX_REGEX,\n)\n\nKEY = r'{words}({closing})?'.format(\n    words=AFFIX_REGEX,\n    closing=CLOSING,\n)\n\nFOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX = re.compile(\n    # e.g. var: MY_PASSWORD_123\n    r'{whitespace}({key})?:{whitespace}({quote}?){words}{denylist}({closing})?(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        quote=QUOTE,\n        words=AFFIX_REGEX,\n        denylist=DENY_LIST_REGEX2,\n        closing=CLOSING,\n    ),\n    flags=re.IGNORECASE,\n)\n\nQUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX = re.compile(\n    # e.g. var: MY_PASSWORD_123\n    r'{whitespace}\"({key})?\":{whitespace}(\"?){words}{denylist}({closing})?(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        words=AFFIX_REGEX,\n        denylist=DENY_LIST_REGEX2,\n        closing=CLOSING,\n    ),\n    flags=re.IGNORECASE,\n)\n\nFOLLOWED_BY_COLON_VALUE_SECRET_REGEX = re.compile(\n    # e.g. var: Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==\n    r'{whitespace}({key})?:{whitespace}({quote}?)({secret})(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        quote=QUOTE,\n        secret=SECRET,\n    ),\n    flags=re.IGNORECASE,\n)\n\nQUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_SECRET_REGEX = re.compile(\n    # e.g. var: Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==\n    r'{whitespace}\"({key})?\":{whitespace}(\"?)({secret})(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        secret=SECRET,\n    ),\n    flags=re.IGNORECASE,\n)\n\nFOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX = re.compile(\n    # e.g. var = MY_PASSWORD_123\n    r'{whitespace}({key})?={whitespace}({quote}?){words}{denylist}({closing})?(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        quote=QUOTE,\n        words=AFFIX_REGEX,\n        denylist=DENY_LIST_REGEX2,\n        closing=CLOSING,\n    ),\n    flags=re.IGNORECASE,\n)\n\nFOLLOWED_BY_EQUAL_VALUE_SECRET_REGEX = re.compile(\n    # e.g. var = Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==\n    r'{whitespace}({key})?={whitespace}({quote}?)({secret})(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        quote=QUOTE,\n        secret=SECRET,\n    ),\n    flags=re.IGNORECASE,\n)\n\nALLOW_LIST = ('secretsmanager', \"secretName\", \"secret_name\", \"creation_token\")  # can add more keys like that\nALLOW_LIST_REGEX = r'|'.join(ALLOW_LIST)\n# Support for suffix of function name i.e \"secretsmanager:GetSecretValue\"\nCAMEL_CASE_NAMES = r'[A-Z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*'\nFUNCTION_CALL_AFTER_KEYWORD_REGEX = re.compile(r'({allowlist})\\s*(:|=)\\s*{suffix}'.format(\n    allowlist=ALLOW_LIST_REGEX,\n    suffix=AFFIX_REGEX,\n))\n\n#  if the current regex is not enough, can add more regexes to check\n\nYML_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {\n    FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX: 4,\n}\n\nYML_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {\n    FOLLOWED_BY_COLON_VALUE_SECRET_REGEX: 4,\n}\n\nJSON_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {\n    QUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX: 4,\n}\n\nJSON_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {\n    QUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_SECRET_REGEX: 4,\n}\n\nTERRAFORM_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {\n    FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX: 4,\n}\n\nTERRAFORM_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {\n    FOLLOWED_BY_EQUAL_VALUE_SECRET_REGEX: 4,\n}\n\nREGEX_VALUE_KEYWORD_BY_FILETYPE = {\n    FileType.YAML: YML_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,\n    FileType.JSON: JSON_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,\n    FileType.TERRAFORM: TERRAFORM_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,\n}\n\nREGEX_VALUE_SECRET_BY_FILETYPE = {\n    FileType.YAML: YML_PAIR_VALUE_SECRET_REGEX_TO_GROUP,\n    FileType.JSON: JSON_PAIR_VALUE_SECRET_REGEX_TO_GROUP,\n    FileType.TERRAFORM: TERRAFORM_PAIR_VALUE_SECRET_REGEX_TO_GROUP,\n}\n\nSINGLE_LINE_PARSER = {\n    FileType.TERRAFORM: terraform_single_line_parser,\n}\n\nMULTILINE_PARSERS = {\n    FileType.YAML: (\n        (FileType.YAML, yml_multiline_parser),\n    ),\n    FileType.JSON: (\n        (FileType.JSON, json_multiline_parser),\n    ),\n    FileType.TERRAFORM: (\n        (FileType.TERRAFORM, terraform_multiline_parser),\n        (FileType.JSON, json_multiline_parser),\n        (FileType.YAML, yml_multiline_parser),\n    ),\n}\n\n\ndef remove_fp_secrets_in_keys(detected_secrets: set[PotentialSecret], line: str, is_code_file: bool = False) -> None:\n    formatted_line = line.replace('\"', '').replace(\"'\", '')\n    secrets_to_remove = set()\n    for detected_secret in detected_secrets:\n        if not detected_secret.secret_value:\n            continue\n        # Found keyword prefix as potential secret\n        if formatted_line.startswith(detected_secret.secret_value):\n            secrets_to_remove.add(detected_secret)\n        # found a function name at the end of the line\n        if formatted_line and FUNCTION_CALL_AFTER_KEYWORD_REGEX.search(formatted_line):\n            secrets_to_remove.add(detected_secret)\n        # secret value is substring of keywork\n        if is_code_file and FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX.search(formatted_line):\n            key, value = line.split(\"=\", 1)\n            if detected_secret.secret_value in key and detected_secret.secret_value in value:\n                secrets_to_remove.add(detected_secret)\n    detected_secrets -= secrets_to_remove\n\n\ndef format_reducing_noise_secret(string: str) -> str:\n    return json.dumps(string)\n\n\ndef extract_from_string(pattern: dict[Pattern[str], int] | None, string: str) -> set[str]:\n    matches: set[str] = set()\n    if not pattern:\n        return matches\n    for value_regex, group_number in pattern.items():\n        match = value_regex.search(string)\n        if match:\n            matches |= {match.group(group_number).rstrip('\\n')}\n    return matches\n\n\ndef detect_secret(\n        scanners: tuple[BasePlugin, ...],\n        filename: str,\n        line: str,\n        line_number: int = 0,\n        is_multiline: Optional[bool] = None,\n        **kwargs: Any,\n) -> set[PotentialSecret]:\n    for scanner in scanners:\n        matches = scanner.analyze_line(filename, line, line_number, **kwargs)\n        if matches:\n            if is_multiline:\n                mark_set_multiline(matches)\n            return matches\n    return set()\n\n\ndef analyze_multiline_keyword_combinator(\n        filename: str,\n        scanners: tuple[BasePlugin, ...],\n        multiline_parser: BaseMultiLineParser,\n        line_number: int,\n        context: CodeSnippet | None = None,\n        raw_context: CodeSnippet | None = None,\n        value_pattern: dict[Pattern[str], int] | None = None,\n        secret_pattern: dict[Pattern[str], int] | None = None,\n        is_added: bool = False,\n        is_removed: bool = False,\n        **kwargs: Any,\n) -> set[PotentialSecret]:\n    secrets: set[PotentialSecret] = set()\n    if context is None or raw_context is None:\n        return secrets\n    value_secrets = extract_from_string(pattern=secret_pattern, string=context.target_line)\n    for possible_secret in value_secrets:\n        secret_adjust = format_reducing_noise_secret(possible_secret)\n\n        potential_secrets = detect_secret(\n            scanners=scanners,\n            filename=filename,\n            line=secret_adjust,\n            line_number=line_number,\n            is_added=is_added,\n            is_removed=is_removed,\n            is_multiline=True,  # always true because we check here for multiline\n            kwargs=kwargs\n        )\n\n        if potential_secrets:\n            possible_keywords: set[str] = set()\n            backwards_range = range(context.target_index - 1, -1, -1)\n            forward_range = range(context.target_index + 1, len(context.lines))\n\n            possible_keywords |= multiline_parser.get_lines_from_same_object(\n                search_range=forward_range,\n                context=context,\n                raw_context=raw_context,\n                line_length_limit=MAX_KEYWORD_LIMIT)\n            possible_keywords |= multiline_parser.get_lines_from_same_object(\n                search_range=backwards_range,\n                context=context,\n                raw_context=raw_context,\n                line_length_limit=MAX_KEYWORD_LIMIT)\n\n            for other_value in possible_keywords:\n                if extract_from_string(pattern=value_pattern, string=other_value):\n                    secrets |= potential_secrets\n                    break\n    return secrets\n\n\ndef mark_set_multiline(secrets: set[PotentialSecret]) -> None:\n    for sec in secrets:\n        sec.is_multiline = True\n", "path": "checkov/secrets/plugins/detector_utils.py"}], "after_files": [{"content": "from __future__ import annotations\n\nimport json\nimport re\nfrom re import Pattern\nfrom typing import Any, TYPE_CHECKING, Optional\n\nfrom detect_secrets.util.filetype import FileType\nfrom detect_secrets.plugins.keyword import DENYLIST\nfrom detect_secrets.plugins.keyword import AFFIX_REGEX\nfrom detect_secrets.plugins.keyword import CLOSING\nfrom detect_secrets.plugins.keyword import OPTIONAL_WHITESPACE\nfrom detect_secrets.plugins.keyword import QUOTE\nfrom detect_secrets.plugins.keyword import SECRET\n\nfrom checkov.secrets.parsers.terraform.multiline_parser import terraform_multiline_parser\nfrom checkov.secrets.parsers.terraform.single_line_parser import terraform_single_line_parser\nfrom checkov.secrets.parsers.yaml.multiline_parser import yml_multiline_parser\nfrom checkov.secrets.parsers.json.multiline_parser import json_multiline_parser\n\nif TYPE_CHECKING:\n    from checkov.secrets.parsers.multiline_parser import BaseMultiLineParser\n    from detect_secrets.core.potential_secret import PotentialSecret\n    from detect_secrets.util.code_snippet import CodeSnippet\n    from detect_secrets.plugins.base import BasePlugin\n\nMAX_KEYWORD_LIMIT = 500\n\nDENY_LIST_REGEX = r'|'.join(DENYLIST)\n# Support for suffix after keyword i.e. password_secure = \"value\"\nDENY_LIST_REGEX2 = r'({denylist}){suffix}'.format(\n    denylist=DENY_LIST_REGEX,\n    suffix=AFFIX_REGEX,\n)\n\nKEY = r'{words}({closing})?'.format(\n    words=AFFIX_REGEX,\n    closing=CLOSING,\n)\n\nFOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX = re.compile(\n    # e.g. var: MY_PASSWORD_123\n    r'{whitespace}({key})?:{whitespace}({quote}?){words}{denylist}({closing})?(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        quote=QUOTE,\n        words=AFFIX_REGEX,\n        denylist=DENY_LIST_REGEX2,\n        closing=CLOSING,\n    ),\n    flags=re.IGNORECASE,\n)\n\nQUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX = re.compile(\n    # e.g. var: MY_PASSWORD_123\n    r'{whitespace}\"({key})?\":{whitespace}(\"?){words}{denylist}({closing})?(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        words=AFFIX_REGEX,\n        denylist=DENY_LIST_REGEX2,\n        closing=CLOSING,\n    ),\n    flags=re.IGNORECASE,\n)\n\nFOLLOWED_BY_COLON_VALUE_SECRET_REGEX = re.compile(\n    # e.g. var: Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==\n    r'{whitespace}({key})?:{whitespace}({quote}?)({secret})(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        quote=QUOTE,\n        secret=SECRET,\n    ),\n    flags=re.IGNORECASE,\n)\n\nQUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_SECRET_REGEX = re.compile(\n    # e.g. var: Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==\n    r'{whitespace}\"({key})?\":{whitespace}(\"?)({secret})(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        secret=SECRET,\n    ),\n    flags=re.IGNORECASE,\n)\n\nFOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX = re.compile(\n    # e.g. var = MY_PASSWORD_123\n    r'{whitespace}({key})?={whitespace}({quote}?){words}{denylist}({closing})?(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        quote=QUOTE,\n        words=AFFIX_REGEX,\n        denylist=DENY_LIST_REGEX2,\n        closing=CLOSING,\n    ),\n    flags=re.IGNORECASE,\n)\n\nFOLLOWED_BY_EQUAL_VALUE_SECRET_REGEX = re.compile(\n    # e.g. var = Zmlyc3Rfc2VjcmV0X2hlcmVfd2hvYV9tdWx0aWxsaW5lX3Nob3VsZF93b3JrXzE==\n    r'{whitespace}({key})?={whitespace}({quote}?)({secret})(\\3)'.format(\n        key=KEY,\n        whitespace=OPTIONAL_WHITESPACE,\n        quote=QUOTE,\n        secret=SECRET,\n    ),\n    flags=re.IGNORECASE,\n)\n\nALLOW_LIST = (  # can add more keys like that\n    'secretsmanager',\n    \"secretName\",\n    \"secret_name\",\n    \"creation_token\",\n    \"client_secret_setting_name\",\n)\nALLOW_LIST_REGEX = r'|'.join(ALLOW_LIST)\n# Support for suffix of function name i.e \"secretsmanager:GetSecretValue\"\nCAMEL_CASE_NAMES = r'[A-Z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*'\nFUNCTION_CALL_AFTER_KEYWORD_REGEX = re.compile(r'({allowlist})\\s*(:|=)\\s*{suffix}'.format(\n    allowlist=ALLOW_LIST_REGEX,\n    suffix=AFFIX_REGEX,\n))\n\n#  if the current regex is not enough, can add more regexes to check\n\nYML_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {\n    FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX: 4,\n}\n\nYML_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {\n    FOLLOWED_BY_COLON_VALUE_SECRET_REGEX: 4,\n}\n\nJSON_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {\n    QUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_KEYWORD_REGEX: 4,\n}\n\nJSON_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {\n    QUOTES_REQUIRED_FOLLOWED_BY_COLON_VALUE_SECRET_REGEX: 4,\n}\n\nTERRAFORM_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP = {\n    FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX: 4,\n}\n\nTERRAFORM_PAIR_VALUE_SECRET_REGEX_TO_GROUP = {\n    FOLLOWED_BY_EQUAL_VALUE_SECRET_REGEX: 4,\n}\n\nREGEX_VALUE_KEYWORD_BY_FILETYPE = {\n    FileType.YAML: YML_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,\n    FileType.JSON: JSON_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,\n    FileType.TERRAFORM: TERRAFORM_PAIR_VALUE_KEYWORD_REGEX_TO_GROUP,\n}\n\nREGEX_VALUE_SECRET_BY_FILETYPE = {\n    FileType.YAML: YML_PAIR_VALUE_SECRET_REGEX_TO_GROUP,\n    FileType.JSON: JSON_PAIR_VALUE_SECRET_REGEX_TO_GROUP,\n    FileType.TERRAFORM: TERRAFORM_PAIR_VALUE_SECRET_REGEX_TO_GROUP,\n}\n\nSINGLE_LINE_PARSER = {\n    FileType.TERRAFORM: terraform_single_line_parser,\n}\n\nMULTILINE_PARSERS = {\n    FileType.YAML: (\n        (FileType.YAML, yml_multiline_parser),\n    ),\n    FileType.JSON: (\n        (FileType.JSON, json_multiline_parser),\n    ),\n    FileType.TERRAFORM: (\n        (FileType.TERRAFORM, terraform_multiline_parser),\n        (FileType.JSON, json_multiline_parser),\n        (FileType.YAML, yml_multiline_parser),\n    ),\n}\n\n\ndef remove_fp_secrets_in_keys(detected_secrets: set[PotentialSecret], line: str, is_code_file: bool = False) -> None:\n    formatted_line = line.replace('\"', '').replace(\"'\", '')\n    secrets_to_remove = set()\n    for detected_secret in detected_secrets:\n        if not detected_secret.secret_value:\n            continue\n        # Found keyword prefix as potential secret\n        if formatted_line.startswith(detected_secret.secret_value):\n            secrets_to_remove.add(detected_secret)\n        # found a function name at the end of the line\n        if formatted_line and FUNCTION_CALL_AFTER_KEYWORD_REGEX.search(formatted_line):\n            secrets_to_remove.add(detected_secret)\n        # secret value is substring of keywork\n        if is_code_file and FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX.search(formatted_line):\n            key, value = line.split(\"=\", 1)\n            if detected_secret.secret_value in key and detected_secret.secret_value in value:\n                secrets_to_remove.add(detected_secret)\n    detected_secrets -= secrets_to_remove\n\n\ndef format_reducing_noise_secret(string: str) -> str:\n    return json.dumps(string)\n\n\ndef extract_from_string(pattern: dict[Pattern[str], int] | None, string: str) -> set[str]:\n    matches: set[str] = set()\n    if not pattern:\n        return matches\n    for value_regex, group_number in pattern.items():\n        match = value_regex.search(string)\n        if match:\n            matches |= {match.group(group_number).rstrip('\\n')}\n    return matches\n\n\ndef detect_secret(\n        scanners: tuple[BasePlugin, ...],\n        filename: str,\n        line: str,\n        line_number: int = 0,\n        is_multiline: Optional[bool] = None,\n        **kwargs: Any,\n) -> set[PotentialSecret]:\n    for scanner in scanners:\n        matches = scanner.analyze_line(filename, line, line_number, **kwargs)\n        if matches:\n            if is_multiline:\n                mark_set_multiline(matches)\n            return matches\n    return set()\n\n\ndef analyze_multiline_keyword_combinator(\n        filename: str,\n        scanners: tuple[BasePlugin, ...],\n        multiline_parser: BaseMultiLineParser,\n        line_number: int,\n        context: CodeSnippet | None = None,\n        raw_context: CodeSnippet | None = None,\n        value_pattern: dict[Pattern[str], int] | None = None,\n        secret_pattern: dict[Pattern[str], int] | None = None,\n        is_added: bool = False,\n        is_removed: bool = False,\n        **kwargs: Any,\n) -> set[PotentialSecret]:\n    secrets: set[PotentialSecret] = set()\n    if context is None or raw_context is None:\n        return secrets\n    value_secrets = extract_from_string(pattern=secret_pattern, string=context.target_line)\n    for possible_secret in value_secrets:\n        secret_adjust = format_reducing_noise_secret(possible_secret)\n\n        potential_secrets = detect_secret(\n            scanners=scanners,\n            filename=filename,\n            line=secret_adjust,\n            line_number=line_number,\n            is_added=is_added,\n            is_removed=is_removed,\n            is_multiline=True,  # always true because we check here for multiline\n            kwargs=kwargs\n        )\n\n        if potential_secrets:\n            possible_keywords: set[str] = set()\n            backwards_range = range(context.target_index - 1, -1, -1)\n            forward_range = range(context.target_index + 1, len(context.lines))\n\n            possible_keywords |= multiline_parser.get_lines_from_same_object(\n                search_range=forward_range,\n                context=context,\n                raw_context=raw_context,\n                line_length_limit=MAX_KEYWORD_LIMIT)\n            possible_keywords |= multiline_parser.get_lines_from_same_object(\n                search_range=backwards_range,\n                context=context,\n                raw_context=raw_context,\n                line_length_limit=MAX_KEYWORD_LIMIT)\n\n            for other_value in possible_keywords:\n                if extract_from_string(pattern=value_pattern, string=other_value):\n                    secrets |= potential_secrets\n                    break\n    return secrets\n\n\ndef mark_set_multiline(secrets: set[PotentialSecret]) -> None:\n    for sec in secrets:\n        sec.is_multiline = True\n", "path": "checkov/secrets/plugins/detector_utils.py"}]}