feat(aws): Add new check opensearch_service_domains_access_control_enabled (#5203)

Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com>
This commit is contained in:
Amogh Bantwal
2024-09-27 07:13:43 -07:00
committed by GitHub
parent c047b29140
commit 853b833cfb
4 changed files with 152 additions and 0 deletions
@@ -127,6 +127,9 @@ class OpenSearchService(AWSService):
"ServiceSoftwareOptions"
]["UpdateAvailable"]
domain.version = describe_domain["DomainStatus"]["EngineVersion"]
domain.advanced_settings_enabled = describe_domain["DomainStatus"][
"AdvancedSecurityOptions"
]["Enabled"]
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
@@ -169,3 +172,4 @@ class OpenSearchDomain(BaseModel):
update_available: bool = None
version: str = None
tags: Optional[list] = []
advanced_settings_enabled: bool = None
@@ -0,0 +1,30 @@
{
"Provider": "aws",
"CheckID": "opensearch_service_domains_access_control_enabled",
"CheckTitle": "Check if Amazon Elasticsearch/Opensearch Service domains have fine grained access control enabled",
"CheckType": [],
"ServiceName": "opensearch",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "high",
"ResourceType": "AwsOpenSearchServiceDomain",
"Description": "Check if Amazon Elasticsearch/Opensearch Service domains have fine grained access control enabled",
"Risk": "Amazon ES's fine graine access control enhances security by verifying that access to OpenSearch domains is controlled at a granular level, allowing for more precise permissions management and reducing the risk of unauthorised access.",
"RelatedUrl": "https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/opensearch-controls.html#opensearch-7",
"Terraform": ""
},
"Recommendation": {
"Text": "Enable fine grained access control for your OpenSearch domains",
"Url": "https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html#fgac-enabling"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
@@ -0,0 +1,24 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.opensearch.opensearch_client import (
opensearch_client,
)
class opensearch_service_domains_access_control_enabled(Check):
def execute(self):
findings = []
for domain in opensearch_client.opensearch_domains:
report = Check_Report_AWS(self.metadata())
report.region = domain.region
report.resource_id = domain.name
report.resource_arn = domain.arn
report.resource_tags = domain.tags
report.status = "FAIL"
report.status_extended = f"Opensearch domain {domain.name} does not have fine grained access control enabled."
if domain.advanced_settings_enabled:
report.status = "PASS"
report.status_extended = f"Opensearch domain {domain.name} has fine grained access control enabled."
findings.append(report)
return findings
@@ -0,0 +1,94 @@
from re import search
from unittest import mock
from prowler.providers.aws.services.opensearch.opensearch_service import (
OpenSearchDomain,
)
from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_EU_WEST_1
domain_name = "test-domain"
domain_arn = f"arn:aws:es:us-west-2:{AWS_ACCOUNT_NUMBER}:domain/{domain_name}"
class Test_opensearch_service_domains_access_control_enabled:
def test_no_domains(self):
opensearch_client = mock.MagicMock
opensearch_client.opensearch_domains = []
with mock.patch(
"prowler.providers.aws.services.opensearch.opensearch_service.OpenSearchService",
new=opensearch_client,
), mock.patch(
"prowler.providers.aws.services.opensearch.opensearch_service_domains_access_control_enabled.opensearch_service_domains_access_control_enabled.opensearch_client",
new=opensearch_client,
):
from prowler.providers.aws.services.opensearch.opensearch_service_domains_access_control_enabled.opensearch_service_domains_access_control_enabled import (
opensearch_service_domains_access_control_enabled,
)
check = opensearch_service_domains_access_control_enabled()
result = check.execute()
assert len(result) == 0
def test_no_fine_grained_access_enabled(self):
opensearch_client = mock.MagicMock
opensearch_client.opensearch_domains = []
opensearch_client.opensearch_domains.append(
OpenSearchDomain(
name=domain_name, region=AWS_REGION_EU_WEST_1, arn=domain_arn
)
)
opensearch_client.opensearch_domains[0].advanced_settings_enabled = False
with mock.patch(
"prowler.providers.aws.services.opensearch.opensearch_service.OpenSearchService",
new=opensearch_client,
), mock.patch(
"prowler.providers.aws.services.opensearch.opensearch_service_domains_access_control_enabled.opensearch_service_domains_access_control_enabled.opensearch_client",
new=opensearch_client,
):
from prowler.providers.aws.services.opensearch.opensearch_service_domains_access_control_enabled.opensearch_service_domains_access_control_enabled import (
opensearch_service_domains_access_control_enabled,
)
check = opensearch_service_domains_access_control_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have fine grained access control enabled.",
result[0].status_extended,
)
assert result[0].resource_id == domain_name
assert result[0].resource_arn == domain_arn
def test_logging_AUDIT_LOGS_enabled(self):
opensearch_client = mock.MagicMock
opensearch_client.opensearch_domains = []
opensearch_client.opensearch_domains.append(
OpenSearchDomain(
name=domain_name, region=AWS_REGION_EU_WEST_1, arn=domain_arn
)
)
opensearch_client.opensearch_domains[0].advanced_settings_enabled = True
with mock.patch(
"prowler.providers.aws.services.opensearch.opensearch_service.OpenSearchService",
new=opensearch_client,
), mock.patch(
"prowler.providers.aws.services.opensearch.opensearch_service_domains_access_control_enabled.opensearch_service_domains_access_control_enabled.opensearch_client",
new=opensearch_client,
):
from prowler.providers.aws.services.opensearch.opensearch_service_domains_access_control_enabled.opensearch_service_domains_access_control_enabled import (
opensearch_service_domains_access_control_enabled,
)
check = opensearch_service_domains_access_control_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has fine grained access control enabled.", result[0].status_extended
)
assert result[0].resource_id == domain_name
assert result[0].resource_arn == domain_arn