From 4dbebac71f2e66118613cfb25fc48dbde79867a1 Mon Sep 17 00:00:00 2001 From: gruebel Date: Mon, 3 Jul 2023 20:51:46 +0200 Subject: [PATCH] improve check logic --- .../resource/generic/ClearTextAPIKey.py | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/checkov/openapi/checks/resource/generic/ClearTextAPIKey.py b/checkov/openapi/checks/resource/generic/ClearTextAPIKey.py index f73c15416da..9575799e113 100644 --- a/checkov/openapi/checks/resource/generic/ClearTextAPIKey.py +++ b/checkov/openapi/checks/resource/generic/ClearTextAPIKey.py @@ -3,6 +3,7 @@ from typing import Any from checkov.common.models.enums import CheckResult, CheckCategories from checkov.common.checks.enums import BlockType +from checkov.common.util.consts import LINE_FIELD_NAMES from checkov.openapi.checks.base_openapi_check import BaseOpenapiCheck @@ -10,46 +11,48 @@ class ClearTestAPIKey(BaseOpenapiCheck): def __init__(self) -> None: id = "CKV_OPENAPI_20" name = "Ensure that API keys are not sent over cleartext" - categories = [CheckCategories.API_SECURITY] - supported_resources = ['paths'] - self.irrelevant_keys = ['__startline__', '__endline__'] + categories = (CheckCategories.API_SECURITY,) + supported_resources = ('paths',) super().__init__(name=name, id=id, categories=categories, supported_entities=supported_resources, block_type=BlockType.DOCUMENT) def scan_entity_conf(self, conf: dict[str, Any], entity_type: str) -> tuple[CheckResult, dict[str, Any]]: # type:ignore[override] # return type is different than the base class - if conf.get("components"): - components = conf.get("components", {}) or {} - security_schemes = components.get("securitySchemes", {}) or {} - elif conf.get("securityDefinitions"): - security_schemes = conf.get("securityDefinitions", {}) or {} + components = conf.get("components") + security_def = conf.get("securityDefinitions") + if components and isinstance(components, dict): + security_schemes = components.get("securitySchemes") or {} + elif security_def: + security_schemes = security_def else: return CheckResult.PASSED, conf - paths = conf.get('paths', {}) or {} + paths = conf.get('paths') + if not isinstance(paths, dict): + return CheckResult.PASSED, security_schemes filtered_dict = {} if isinstance(security_schemes, dict): for name, scheme in security_schemes.items(): - if isinstance(scheme, dict) and "type" in scheme and scheme['type'] == "apiKey": + if isinstance(scheme, dict) and scheme.get('type') == "apiKey": filtered_dict[name] = scheme if not filtered_dict: return CheckResult.PASSED, security_schemes - if not isinstance(paths, dict): - return CheckResult.PASSED, security_schemes for key, path in paths.items(): if not path: continue - if key in self.irrelevant_keys: + if key in LINE_FIELD_NAMES: continue - for _operation, value in path.items(): + for value in path.values(): if not isinstance(value, dict): continue - if value.get('security'): - for sec in value['security'][0]: + operation_security = value.get('security') + if operation_security and isinstance(operation_security, list): + for sec in operation_security[0]: if sec in filtered_dict: return CheckResult.FAILED, security_schemes + return CheckResult.PASSED, conf