Skip to content

Commit

Permalink
improve check logic
Browse files Browse the repository at this point in the history
  • Loading branch information
gruebel committed Jul 3, 2023
1 parent ecb44a3 commit 4dbebac
Showing 1 changed file with 19 additions and 16 deletions.
35 changes: 19 additions & 16 deletions checkov/openapi/checks/resource/generic/ClearTextAPIKey.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,56 @@
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


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


Expand Down

0 comments on commit 4dbebac

Please sign in to comment.