Skip to content

Commit

Permalink
Merge branch 'main' into param-store-check-dec24
Browse files Browse the repository at this point in the history
  • Loading branch information
tsmithv11 authored Dec 23, 2024
2 parents 7ee12d8 + 91b57c3 commit 0ef3156
Show file tree
Hide file tree
Showing 20 changed files with 501 additions and 18 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# CHANGELOG

## [Unreleased](https://github.com/bridgecrewio/checkov/compare/3.2.342...HEAD)
## [Unreleased](https://github.com/bridgecrewio/checkov/compare/3.2.344...HEAD)

## [3.2.344](https://github.com/bridgecrewio/checkov/compare/3.2.342...3.2.344) - 2024-12-21

### Bug Fix

- **kubernetes:** Add to nested resources on k8s graph inherit namespace - [#6912](https://github.com/bridgecrewio/checkov/pull/6912)

## [3.2.342](https://github.com/bridgecrewio/checkov/compare/3.2.339...3.2.342) - 2024-12-18

Expand Down
2 changes: 2 additions & 0 deletions checkov/common/util/env_vars_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ def __init__(self) -> None:
self.HCL_PARSE_TIMEOUT_SEC = force_int(os.getenv("HCL_PARSE_TIMEOUT_SEC", 10))
self.ENABLE_DOTNET_CPM = os.getenv('ENABLE_DOTNET_CPM', False)
self.JAVA_FULL_DT = os.getenv('JAVA_FULL_DT', False)
self.PROXY_CA_PATH = os.getenv('PROXY_CA_PATH', None)
self.PROXY_URL = os.getenv('PROXY_URL', None)


env_vars_config = EnvVarsConfig()
6 changes: 6 additions & 0 deletions checkov/kubernetes/graph_builder/local_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ def _extract_nested_resources_recursive(conf: Dict[str, Any], all_resources: Lis
template['apiVersion'] = conf.get('apiVersion')

template_metadata = template.get('metadata')

template_namespace = template_metadata.get('namespace')
metadata_namespace = metadata.get('namespace')
if template_namespace is None and metadata_namespace is not None:
template_metadata['namespace'] = metadata_namespace

annotations = metadata.get('annotations')
if annotations is not None and template_metadata is not None and 'annotations' not in template_metadata:
# Updates annotations to template as well to handle metadata added to the parent resource
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from typing import Any, List, Dict

from checkov.common.models.enums import CheckCategories, CheckResult
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck


class OpenAICognitiveServicesRestrictOutboundNetwork(BaseResourceCheck):
def __init__(self):
name = "Ensure that Azure Cognitive Services account hosted with OpenAI is configured with data loss prevention"
id = "CKV_AZURE_247"
supported_resources = ('azurerm_cognitive_account', )
categories = (CheckCategories.NETWORKING, )
super().__init__(
name=name,
id=id,
categories=categories,
supported_resources=supported_resources,
)

def scan_resource_conf(self, conf: Dict[str, List[Any]]) -> CheckResult:
if conf.get("kind", [""])[0].lower() != 'openai':
return CheckResult.PASSED

outbound_network_access_restricted = conf.get('outbound_network_access_restricted', [None])[0]
fqdns = conf.get('fqdns', [[]])[0]
if not outbound_network_access_restricted or not fqdns:
return CheckResult.FAILED

return CheckResult.PASSED


check = OpenAICognitiveServicesRestrictOutboundNetwork()
6 changes: 5 additions & 1 deletion checkov/terraform/checks/terraform/terraform/StateLock.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ def scan_terraform_block_conf(self, conf: Dict[str, List[Any]]) -> CheckResult:
return CheckResult.UNKNOWN

s3_config = backend["s3"]
if ("use_lockfile" not in s3_config or not s3_config["use_lockfile"]) and "dynamodb_table" not in s3_config:
if isinstance(s3_config, list):
# this can happen for CDKTF output files
s3_config = s3_config[0]

if not s3_config.get("use_lockfile") and "dynamodb_table" not in s3_config:
return CheckResult.FAILED
return CheckResult.PASSED

Expand Down
15 changes: 12 additions & 3 deletions checkov/terraform/module_loading/loaders/registry_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
order_versions_in_descending_order,
get_version_constraints
)
from checkov.terraform.module_loading.proxy_client import call_http_request_with_proxy

if TYPE_CHECKING:
from checkov.terraform.module_loading.module_params import ModuleParams
Expand Down Expand Up @@ -83,11 +84,19 @@ def _load_module(self, module_params: ModuleParams) -> ModuleContent:
logging.debug(f"Best version for {module_params.module_source} is {best_version} based on the version constraint {module_params.version}.")
logging.debug(f"Module download url: {request_download_url}")
try:
response = requests.get(
request = requests.Request(
method='GET',
url=request_download_url,
headers={"Authorization": f"Bearer {module_params.token}"} if module_params.token else None,
timeout=DEFAULT_TIMEOUT
headers={"Authorization": f"Bearer {module_params.token}"} if module_params.token else None
)
if os.getenv('PROXY_URL'):
logging.info('Send request with proxy')
response = call_http_request_with_proxy(request)
else:
session = requests.Session()
prepared_request = session.prepare_request(request)
response = session.send(prepared_request, timeout=DEFAULT_TIMEOUT)

response.raise_for_status()
except HTTPError as e:
self.logger.warning(e)
Expand Down
33 changes: 33 additions & 0 deletions checkov/terraform/module_loading/proxy_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os
from typing import Any

import requests


class ProxyClient:
def __init__(self) -> None:
self.proxy_ca_path = os.getenv('PROXY_CA_PATH', None)
if self.proxy_ca_path is None:
raise Exception("[ProxyClient] CA certificate path is missing")

def get_session(self) -> requests.Session:
if not os.getenv('PROXY_URL', None):
raise Exception('Please provide "PROXY_URL" env var')
proxy_url = os.getenv('PROXY_URL')
session = requests.Session()
proxies = {
"http": proxy_url,
"https": proxy_url,
}
session.proxies.update(proxies) # type: ignore
return session

def send_request(self, request: requests.Request) -> requests.Response:
session = self.get_session()
prepared_request = session.prepare_request(request)
return session.send(prepared_request, verify=self.proxy_ca_path)


def call_http_request_with_proxy(request: requests.Request) -> Any:
proxy_client = ProxyClient()
return proxy_client.send_request(request=request)
2 changes: 1 addition & 1 deletion checkov/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = '3.2.343'
version = '3.2.344'
2 changes: 1 addition & 1 deletion kubernetes/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
checkov==3.2.343
checkov==3.2.344
40 changes: 40 additions & 0 deletions tests/kubernetes/checks/example_NoDefaultNamespace/Dev-PASSED.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: v1
kind: Namespace
metadata:
name: dev

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: dev
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pass:
- 'Pod.default.nginx-ingress-controller-2.app.kubernetes.io/name-ingress-nginx.app.kubernetes.io/part-of-ingress-nginx'
- 'Pod.example-ns.nginx-ingress-controller-2.app.kubernetes.io/name-ingress-nginx.app.kubernetes.io/part-of-ingress-nginx'
fail:
- 'Pod.default.nginx-ingress-controller.app.kubernetes.io/name-ingress-nginx.app.kubernetes.io/part-of-ingress-nginx'
- 'Pod.example-ns.nginx-ingress-controller.app.kubernetes.io/name-ingress-nginx.app.kubernetes.io/part-of-ingress-nginx'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pass:
- 'Pod.dev.nginx-deployment.app-nginx'
- 'Deployment.dev.nginx-deployment'
- 'Service.dev.nginx-service'
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: v1
kind: Namespace
metadata:
name: dev

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: dev
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
61 changes: 61 additions & 0 deletions tests/kubernetes/graph/checks/test_checks/NoDefaultNamespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
metadata:
id: "CKV_K8S_160"
name: "Ensure resources in k8s not in default namespace"
category: "KUBERNETES"
definition:
and:
- cond_type: "attribute"
resource_types:
- "Deployment"
- "StatefulSet"
- "DaemonSet"
- "Job"
- "CronJob"
- "Pod"
- "Service"
- "ConfigMap"
- "Secret"
attribute: "metadata.namespace"
operator: "exists"
- cond_type: "attribute"
resource_types:
- "Deployment"
- "StatefulSet"
- "DaemonSet"
- "Job"
- "CronJob"
- "Pod"
- "Service"
- "ConfigMap"
- "Secret"
attribute: "metadata.namespace"
operator: "not_equals"
value: "default"
- cond_type: "attribute"
resource_types:
- "Deployment"
- "StatefulSet"
- "DaemonSet"
- "Job"
- "CronJob"
- "Pod"
- "Service"
- "ConfigMap"
- "Secret"
attribute: "metadata.namespace"
operator: "not_equals"
value: "kube-system"
- cond_type: "attribute"
resource_types:
- "Deployment"
- "StatefulSet"
- "DaemonSet"
- "Job"
- "CronJob"
- "Pod"
- "Service"
- "ConfigMap"
- "Secret"
attribute: "metadata.namespace"
operator: "not_regex_match"
value: "^kube-.*"
3 changes: 3 additions & 0 deletions tests/kubernetes/graph/checks/test_yaml_policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ def test_PodIsPubliclyAccessibleExample(self) -> None:
def test_RequireAllPodsToHaveNetworkPolicy(self) -> None:
self.go('RequireAllPodsToHaveNetworkPolicy')

def test_NoDefaultNamespace(self):
self.go('NoDefaultNamespace')

def create_report_from_graph_checks_results(self, checks_results, check):
report = Report("kubernetes")
first_results_key = list(checks_results.keys())[0]
Expand Down
Loading

0 comments on commit 0ef3156

Please sign in to comment.