/
OperationObjectImplicitFlow.py
54 lines (46 loc) · 2.31 KB
/
OperationObjectImplicitFlow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from __future__ import annotations
from typing import Any
from checkov.common.models.enums import CheckResult, CheckCategories
from checkov.common.checks.enums import BlockType
from checkov.openapi.checks.resource.v2.BaseOpenapiCheckV2 import BaseOpenapiCheckV2
class OperationObjectImplicitFlow(BaseOpenapiCheckV2):
def __init__(self) -> None:
id = "CKV_OPENAPI_14"
name = "Ensure that operation objects do not use 'implicit' flow, which is deprecated - version 2.0 files"
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_openapi_conf(self, conf: dict[str, Any], entity_type: str) -> tuple[CheckResult, dict[str, Any]]:
paths = conf.get('paths') or {}
security_definitions = conf.get('securityDefinitions') or {}
for path, path_dict in paths.items():
if self.is_start_end_line(path):
continue
if not isinstance(path_dict, dict):
return CheckResult.UNKNOWN, conf
for operation, operation_dict in path_dict.items():
if self.is_start_end_line(operation):
continue
if not isinstance(operation_dict, dict):
return CheckResult.UNKNOWN, conf
security = operation_dict.get('security', [])
for security_definition in security:
if not isinstance(security_definition, dict):
return CheckResult.UNKNOWN, conf
for auth_key in security_definition:
if self.is_start_end_line(auth_key):
continue
if not isinstance(security_definitions, dict):
return CheckResult.UNKNOWN, conf
auth_definition = security_definitions.get(auth_key, {})
auth_flow = auth_definition.get('flow', '')
if auth_flow == 'implicit':
return CheckResult.FAILED, auth_definition
return CheckResult.PASSED, conf
check = OperationObjectImplicitFlow()