feat(Glue): add Glue tests and checks (#1495)

Co-authored-by: sergargar <sergio@verica.io>
Co-authored-by: Pepe Fagoaga <pepe@verica.io>
This commit is contained in:
Sergio Garcia
2022-11-17 21:06:15 +01:00
committed by GitHub
parent 967990b76d
commit bfc8c90abb
52 changed files with 2248 additions and 540 deletions

View File

@@ -14,20 +14,21 @@ class directoryservice_directory_snapshots_limit(Check):
report = Check_Report(self.metadata)
report.region = directory.region
report.resource_id = directory.name
if directory.snapshots_limits.manual_snapshots_limit_reached:
report.status = "FAIL"
report.status_extended = f"Directory Service {directory.name} reached {directory.snapshots_limits.manual_snapshots_limit} Snapshots limit"
else:
limit_remaining = (
directory.snapshots_limits.manual_snapshots_limit
- directory.snapshots_limits.manual_snapshots_current_count
)
if limit_remaining <= SNAPSHOT_LIMIT_THRESHOLD:
if directory.snapshots_limits:
if directory.snapshots_limits.manual_snapshots_limit_reached:
report.status = "FAIL"
report.status_extended = f"Directory Service {directory.name} is about to reach {directory.snapshots_limits.manual_snapshots_limit} Snapshots which is the limit"
report.status_extended = f"Directory Service {directory.name} reached {directory.snapshots_limits.manual_snapshots_limit} Snapshots limit"
else:
report.status = "PASS"
report.status_extended = f"Directory Service {directory.name} is using {directory.snapshots_limits.manual_snapshots_current_count} out of {directory.snapshots_limits.manual_snapshots_limit} from the Snapshots Limit"
findings.append(report)
limit_remaining = (
directory.snapshots_limits.manual_snapshots_limit
- directory.snapshots_limits.manual_snapshots_current_count
)
if limit_remaining <= SNAPSHOT_LIMIT_THRESHOLD:
report.status = "FAIL"
report.status_extended = f"Directory Service {directory.name} is about to reach {directory.snapshots_limits.manual_snapshots_limit} Snapshots which is the limit"
else:
report.status = "PASS"
report.status_extended = f"Directory Service {directory.name} is using {directory.snapshots_limits.manual_snapshots_current_count} out of {directory.snapshots_limits.manual_snapshots_limit} from the Snapshots Limit"
findings.append(report)
return findings

View File

@@ -73,25 +73,30 @@ class DirectoryService:
def __list_log_subscriptions__(self, regional_client):
logger.info("DirectoryService - Listing Log Subscriptions...")
try:
for directory in self.directories:
list_log_subscriptions_paginator = regional_client.get_paginator(
"list_log_subscriptions"
)
list_log_subscriptions_parameters = {"DirectoryId": directory}
log_subscriptions = []
for page in list_log_subscriptions_paginator.paginate(
**list_log_subscriptions_parameters
):
for log_subscription_info in page["LogSubscriptions"]:
log_subscriptions.append(
LogSubscriptions(
log_group_name=log_subscription_info["LogGroupName"],
created_date_time=log_subscription_info[
"SubscriptionCreatedDateTime"
],
for directory in self.directories.values():
if directory.region == regional_client.region:
list_log_subscriptions_paginator = regional_client.get_paginator(
"list_log_subscriptions"
)
list_log_subscriptions_parameters = {"DirectoryId": directory.name}
log_subscriptions = []
for page in list_log_subscriptions_paginator.paginate(
**list_log_subscriptions_parameters
):
for log_subscription_info in page["LogSubscriptions"]:
log_subscriptions.append(
LogSubscriptions(
log_group_name=log_subscription_info[
"LogGroupName"
],
created_date_time=log_subscription_info[
"SubscriptionCreatedDateTime"
],
)
)
)
self.directories[directory].log_subscriptions = log_subscriptions
self.directories[
directory.name
].log_subscriptions = log_subscriptions
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
@@ -100,22 +105,23 @@ class DirectoryService:
def __describe_event_topics__(self, regional_client):
logger.info("DirectoryService - Describing Event Topics...")
try:
for directory in self.directories:
describe_event_topics_parameters = {"DirectoryId": directory}
event_topics = []
describe_event_topics = regional_client.describe_event_topics(
**describe_event_topics_parameters
)
for event_topic in describe_event_topics["EventTopics"]:
event_topics.append(
EventTopics(
topic_arn=event_topic["TopicArn"],
topic_name=event_topic["TopicName"],
status=event_topic["Status"],
created_date_time=event_topic["CreatedDateTime"],
)
for directory in self.directories.values():
if directory.region == regional_client.region:
describe_event_topics_parameters = {"DirectoryId": directory.name}
event_topics = []
describe_event_topics = regional_client.describe_event_topics(
**describe_event_topics_parameters
)
self.directories[directory].event_topics = event_topics
for event_topic in describe_event_topics["EventTopics"]:
event_topics.append(
EventTopics(
topic_arn=event_topic["TopicArn"],
topic_name=event_topic["TopicName"],
status=event_topic["Status"],
created_date_time=event_topic["CreatedDateTime"],
)
)
self.directories[directory.name].event_topics = event_topics
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
@@ -124,26 +130,27 @@ class DirectoryService:
def __list_certificates__(self, regional_client):
logger.info("DirectoryService - Listing Certificates...")
try:
for directory in self.directories:
list_certificates_paginator = regional_client.get_paginator(
"list_certificates"
)
list_certificates_parameters = {"DirectoryId": directory}
certificates = []
for page in list_certificates_paginator.paginate(
**list_certificates_parameters
):
for certificate_info in page["CertificatesInfo"]:
certificates.append(
Certificate(
id=certificate_info["CertificateId"],
common_name=certificate_info["CommonName"],
state=certificate_info["State"],
expiry_date_time=certificate_info["ExpiryDateTime"],
type=certificate_info["Type"],
for directory in self.directories.values():
if directory.region == regional_client.region:
list_certificates_paginator = regional_client.get_paginator(
"list_certificates"
)
list_certificates_parameters = {"DirectoryId": directory.name}
certificates = []
for page in list_certificates_paginator.paginate(
**list_certificates_parameters
):
for certificate_info in page["CertificatesInfo"]:
certificates.append(
Certificate(
id=certificate_info["CertificateId"],
common_name=certificate_info["CommonName"],
state=certificate_info["State"],
expiry_date_time=certificate_info["ExpiryDateTime"],
type=certificate_info["Type"],
)
)
)
self.directories[directory].certificates = certificates
self.directories[directory.name].certificates = certificates
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
@@ -152,24 +159,23 @@ class DirectoryService:
def __get_snapshot_limits__(self, regional_client):
logger.info("DirectoryService - Getting Snapshot Limits...")
try:
for directory in self.directories:
get_snapshot_limits_parameters = {"DirectoryId": directory}
snapshot_limit = regional_client.get_snapshot_limits(
**get_snapshot_limits_parameters
)
self.directories[directory].snapshots_limits = SnapshotLimit(
manual_snapshots_current_count=snapshot_limit["SnapshotLimits"][
"ManualSnapshotsCurrentCount"
],
manual_snapshots_limit=snapshot_limit["SnapshotLimits"][
"ManualSnapshotsLimit"
],
manual_snapshots_limit_reached=snapshot_limit["SnapshotLimits"][
"ManualSnapshotsLimitReached"
],
)
for directory in self.directories.values():
if directory.region == regional_client.region:
get_snapshot_limits_parameters = {"DirectoryId": directory.name}
snapshot_limit = regional_client.get_snapshot_limits(
**get_snapshot_limits_parameters
)
self.directories[directory.name].snapshots_limits = SnapshotLimit(
manual_snapshots_current_count=snapshot_limit["SnapshotLimits"][
"ManualSnapshotsCurrentCount"
],
manual_snapshots_limit=snapshot_limit["SnapshotLimits"][
"ManualSnapshotsLimit"
],
manual_snapshots_limit_reached=snapshot_limit["SnapshotLimits"][
"ManualSnapshotsLimitReached"
],
)
except Exception as error:
logger.error(

View File

View File

@@ -1,53 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7114="7.114"
CHECK_TITLE_extra7114="[extra7114] Check if Glue development endpoints have S3 encryption enabled."
CHECK_SCORED_extra7114="NOT_SCORED"
CHECK_CIS_LEVEL_extra7114="EXTRA"
CHECK_SEVERITY_extra7114="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7114="AwsGlue"
CHECK_ALTERNATE_check7114="extra7114"
CHECK_SERVICENAME_extra7114="glue"
CHECK_RISK_extra7114='Data exfiltration could happen if information is not protected. KMS keys provide additional security level to IAM policies.'
CHECK_REMEDIATION_extra7114='Specify AWS KMS keys to use for input and output from S3 and EBS.'
CHECK_DOC_extra7114='https://docs.aws.amazon.com/glue/latest/dg/encryption-security-configuration.html'
CHECK_CAF_EPIC_extra7114='Data Protection'
extra7114(){
for regx in $REGIONS; do
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json 2>&1)
if [[ $(echo "$LIST_EP_SC" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get dev endpoints" "$regx"
continue
fi
if [[ $LIST_EP_SC != '[]' ]]; then
for ep in $(echo "${LIST_EP_SC}"| jq -r '.[] | @base64');do
ENDPOINT_NAME=$(echo $ep | base64 --decode | jq -r '.Name')
ENDPOINT_SC=$(echo $ep | base64 --decode | jq -r '.Security // empty')
if [[ ! -z "$ENDPOINT_SC" ]]; then
ENDPOINT_SC_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${ENDPOINT_SC}" $PROFILE_OPT --region $regx --query 'SecurityConfiguration.EncryptionConfiguration.S3Encryption[0].S3EncryptionMode' --output text)
if [[ "$ENDPOINT_SC_ENCRYPTION" == "DISABLED" ]]; then
textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have S3 encryption enabled!" "$regx" "$ENDPOINT_NAME"
else
textPass "$regx: Glue development endpoint $ENDPOINT_NAME has S3 encryption enabled" "$regx" "$ENDPOINT_NAME"
fi
else
textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have security configuration" "$regx" "$ENDPOINT_NAME"
fi
done
else
textInfo "$regx: There are no Glue development endpoints" "$regx"
fi
done
}

View File

@@ -1,47 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7115="7.115"
CHECK_TITLE_extra7115="[extra7115] Check if Glue database connection has SSL connection enabled."
CHECK_SCORED_extra7115="NOT_SCORED"
CHECK_CIS_LEVEL_extra7115="EXTRA"
CHECK_SEVERITY_extra7115="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7115="AwsGlue"
CHECK_ALTERNATE_check7115="extra7115"
CHECK_SERVICENAME_extra7115="glue"
CHECK_RISK_extra7115='Data exfiltration could happen if information is not protected in transit.'
CHECK_REMEDIATION_extra7115='Configure encryption settings for crawlers; ETL jobs; and development endpoints using security configurations in AWS Glue.'
CHECK_DOC_extra7115='https://docs.aws.amazon.com/glue/latest/dg/encryption-in-transit.html'
CHECK_CAF_EPIC_extra7115='Data Protection'
extra7115(){
for regx in $REGIONS; do
CONNECTION_LIST=$($AWSCLI glue get-connections $PROFILE_OPT --region $regx --output json --query 'ConnectionList[*].{Name:Name,SSL:ConnectionProperties.JDBC_ENFORCE_SSL}' 2>&1)
if [[ $(echo "$CONNECTION_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get connections" "$regx"
continue
fi
if [[ $CONNECTION_LIST != '[]' ]]; then
for connection in $(echo "${CONNECTION_LIST}" | jq -r '.[] | @base64'); do
CONNECTION_NAME=$(echo $connection | base64 --decode | jq -r '.Name' )
CONNECTION_SSL_STATE=$(echo $connection | base64 --decode | jq -r '.SSL')
if [[ "$CONNECTION_SSL_STATE" == "false" ]]; then
textFail "$regx: Glue connection $CONNECTION_NAME has SSL connection disabled" "$regx" "$CONNECTION_NAME"
else
textPass "$regx: Glue connection $CONNECTION_NAME has SSL connection enabled" "$regx" "$CONNECTION_NAME"
fi
done
else
textInfo "$regx: There are no Glue connections" "$regx"
fi
done
}

View File

@@ -1,44 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7116="7.116"
CHECK_TITLE_extra7116="[extra7116] Check if Glue data catalog settings have metadata encryption enabled."
CHECK_SCORED_extra7116="NOT_SCORED"
CHECK_CIS_LEVEL_extra7116="EXTRA"
CHECK_SEVERITY_extra7116="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7116="AwsGlue"
CHECK_ALTERNATE_check7116="extra7116"
CHECK_SERVICENAME_extra7116="glue"
CHECK_RISK_extra7116='If not enabled sensitive information at rest is not protected.'
CHECK_REMEDIATION_extra7116='Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits.'
CHECK_DOC_extra7116='https://docs.aws.amazon.com/glue/latest/dg/encrypt-glue-data-catalog.html'
CHECK_CAF_EPIC_extra7116='Data Protection'
extra7116(){
for regx in $REGIONS; do
TABLE_LIST=$($AWSCLI glue search-tables --max-results 1 $PROFILE_OPT --region $regx --output text --query 'TableList[*]' 2>&1)
if [[ $(echo "$TABLE_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to search tables" "$regx"
continue
fi
if [[ ! -z $TABLE_LIST ]]; then
METADATA_ENCRYPTED=$($AWSCLI glue get-data-catalog-encryption-settings $PROFILE_OPT --region $regx --output text --query "DataCatalogEncryptionSettings.EncryptionAtRest.CatalogEncryptionMode")
if [[ "$METADATA_ENCRYPTED" == "DISABLED" ]]; then
textFail "$regx: Glue data catalog settings have metadata encryption disabled" "$regx"
else
textPass "$regx: Glue data catalog settings have metadata encryption enabled" "$regx"
fi
else
textInfo "$regx: Glue data catalog settings metadata encryption does not apply since there are no tables" "$regx"
fi
done
}

View File

@@ -1,44 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7117="7.117"
CHECK_TITLE_extra7117="[extra7117] Check if Glue data catalog settings have encrypt connection password enabled."
CHECK_SCORED_extra7117="NOT_SCORED"
CHECK_CIS_LEVEL_extra7117="EXTRA"
CHECK_SEVERITY_extra7117="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7117="AwsGlue"
CHECK_ALTERNATE_check7117="extra7117"
CHECK_SERVICENAME_extra7117="glue"
CHECK_RISK_extra7117='If not enabled sensitive information at rest is not protected.'
CHECK_REMEDIATION_extra7117='On the AWS Glue console; you can enable this option on the Data catalog settings page.'
CHECK_DOC_extra7117='https://docs.aws.amazon.com/glue/latest/dg/encrypt-connection-passwords.html'
CHECK_CAF_EPIC_extra7117='Data Protection'
extra7117(){
for regx in $REGIONS; do
CONNECTION_LIST=$($AWSCLI glue get-connections $PROFILE_OPT --region $regx --output text --query 'ConnectionList[*]' 2>&1)
if [[ $(echo "$CONNECTION_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get connections" "$regx"
continue
fi
if [[ ! -z $CONNECTION_LIST ]]; then
METADATA_ENCRYPTED=$($AWSCLI glue get-data-catalog-encryption-settings $PROFILE_OPT --region $regx --output text --query "DataCatalogEncryptionSettings.ConnectionPasswordEncryption.ReturnConnectionPasswordEncrypted")
if [[ "$METADATA_ENCRYPTED" == "False" ]]; then
textFail "$regx: Glue data catalog connection password is not encrypted" "$regx"
else
textPass "$regx: Glue data catalog connection password is encrypted" "$regx"
fi
else
textInfo "$regx: Glue data catalog connection password encryption does not apply since there are no connections" "$regx"
fi
done
}

View File

@@ -1,59 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7118="7.118"
CHECK_TITLE_extra7118="[extra7118] Check if Glue ETL Jobs have S3 encryption enabled."
CHECK_SCORED_extra7118="NOT_SCORED"
CHECK_CIS_LEVEL_extra7118="EXTRA"
CHECK_SEVERITY_extra7118="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7118="AwsGlue"
CHECK_ALTERNATE_check7118="extra7118"
CHECK_SERVICENAME_extra7118="glue"
CHECK_RISK_extra7118='If not enabled sensitive information at rest is not protected.'
CHECK_REMEDIATION_extra7118='Provide the encryption properties that are used by crawlers; jobs; and development endpoints.'
CHECK_DOC_extra7118='https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html'
CHECK_CAF_EPIC_extra7118='Data Protection'
extra7118(){
for regx in $REGIONS; do
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration,JobEncryption:DefaultArguments."--encryption-type"}' 2>&1)
if [[ $(echo "$JOB_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get jobs" "$regx"
continue
fi
if [[ $JOB_LIST != '[]' ]]; then
for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do
JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name')
SECURITY_CONFIGURATION=$(echo $job | base64 --decode | jq -r '.SecurityConfiguration // empty')
JOB_ENCRYPTION=$(echo $job | base64 --decode | jq -r '.JobEncryption // empty')
if [[ ! -z "$SECURITY_CONFIGURATION" ]]; then
S3_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${SECURITY_CONFIGURATION}" $PROFILE_OPT --region $regx --output text --query 'SecurityConfiguration.EncryptionConfiguration.S3Encryption[0].S3EncryptionMode')
if [[ "$S3_ENCRYPTION" == "DISABLED" ]]; then
if [[ ! -z "$JOB_ENCRYPTION" ]]; then
textPass "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION for S3 encryption enabled" "$regx" "$JOB_NAME"
else
textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" "$JOB_NAME"
fi
else
textPass "$regx: Glue job $JOB_NAME does have $S3_ENCRYPTION for S3 encryption enabled" "$regx" "$JOB_NAME"
fi
elif [[ ! -z "$JOB_ENCRYPTION" ]]; then
textPass "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION for S3 encryption enabled" "$regx" "$JOB_NAME"
else
textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" "$JOB_NAME"
fi
done
else
textInfo "$regx: There are no Glue jobs" "$regx"
fi
done
}

View File

@@ -1,53 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7119="7.119"
CHECK_TITLE_extra7119="[extra7119] Check if Glue development endpoints have CloudWatch logs encryption enabled."
CHECK_SCORED_extra7119="NOT_SCORED"
CHECK_CIS_LEVEL_extra7119="EXTRA"
CHECK_SEVERITY_extra7119="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7119="AwsGlue"
CHECK_ALTERNATE_check7119="extra7119"
CHECK_SERVICENAME_extra7119="glue"
CHECK_RISK_extra7119='If not enabled sensitive information at rest is not protected.'
CHECK_REMEDIATION_extra7119='Enable Encryption in the Security configurations.'
CHECK_DOC_extra7119='https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html'
CHECK_CAF_EPIC_extra7119='Logging and Monitoring'
extra7119(){
for regx in $REGIONS; do
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json 2>&1)
if [[ $(echo "$LIST_EP_SC" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get dev endpoints" "$regx"
continue
fi
if [[ $LIST_EP_SC != '[]' ]]; then
for ep in $(echo "${LIST_EP_SC}"| jq -r '.[] | @base64');do
ENDPOINT_NAME=$(echo $ep | base64 --decode | jq -r '.Name')
ENDPOINT_SC=$(echo $ep | base64 --decode | jq -r '.Security // empty')
if [[ ! -z "$ENDPOINT_SC" ]]; then
ENDPOINT_SC_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${ENDPOINT_SC}" $PROFILE_OPT --region $regx --query 'SecurityConfiguration.EncryptionConfiguration.CloudWatchEncryption.CloudWatchEncryptionMode' --output text)
if [[ $ENDPOINT_SC_ENCRYPTION == "DISABLED" ]]; then
textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have CloudWatch logs encryption enabled!" "$regx" "$ENDPOINT_NAME"
else
textPass "$regx: Glue development endpoint $ENDPOINT_NAME has CloudWatch logs encryption enabled" "$regx" "$ENDPOINT_NAME"
fi
else
textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have security configuration" "$regx" "$ENDPOINT_NAME"
fi
done
else
textInfo "$regx: There are no Glue development endpoints" "$regx"
fi
done
}

View File

@@ -1,52 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7120="7.120"
CHECK_TITLE_extra7120="[extra7120] Check if Glue ETL Jobs have CloudWatch Logs encryption enabled."
CHECK_SCORED_extra7120="NOT_SCORED"
CHECK_CIS_LEVEL_extra7120="EXTRA"
CHECK_SEVERITY_extra7120="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7120="AwsGlue"
CHECK_ALTERNATE_check7120="extra7120"
CHECK_SERVICENAME_extra7120="glue"
CHECK_RISK_extra7120='If not enabled sensitive information at rest is not protected.'
CHECK_REMEDIATION_extra7120='Enable Encryption in the Security configurations.'
CHECK_DOC_extra7120='https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html'
CHECK_CAF_EPIC_extra7120='Logging and Monitoring'
extra7120(){
for regx in $REGIONS; do
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}' 2>&1)
if [[ $(echo "$JOB_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get jobs" "$regx"
continue
fi
if [[ $JOB_LIST != '[]' ]]; then
for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do
JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name')
SECURITY_CONFIGURATION=$(echo $job | base64 --decode | jq -r '.SecurityConfiguration // empty')
if [[ ! -z "$SECURITY_CONFIGURATION" ]]; then
CLOUDWATCH_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${SECURITY_CONFIGURATION}" $PROFILE_OPT --region $regx --output text --query 'SecurityConfiguration.EncryptionConfiguration.CloudWatchEncryption.CloudWatchEncryptionMode')
if [[ "$CLOUDWATCH_ENCRYPTION" == "DISABLED" ]]; then
textFail "$regx: Glue job $JOB_NAME does not have CloudWatch Logs encryption enabled" "$regx" "$JOB_NAME"
else
textPass "$regx: Glue job $JOB_NAME does have $CLOUDWATCH_ENCRYPTION CloudWatch Logs encryption enabled" "$regx" "$JOB_NAME"
fi
else
textFail "$regx: Glue job $JOB_NAME does not have CloudWatch Logs encryption enabled" "$regx" "$JOB_NAME"
fi
done
else
textInfo "$regx: There are no Glue jobs" "$regx"
fi
done
}

View File

@@ -1,53 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7121="7.121"
CHECK_TITLE_extra7121="[extra7121] Check if Glue development endpoints have Job bookmark encryption enabled."
CHECK_SCORED_extra7121="NOT_SCORED"
CHECK_CIS_LEVEL_extra7121="EXTRA"
CHECK_SEVERITY_extra7121="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7121="AwsGlue"
CHECK_ALTERNATE_check7121="extra7121"
CHECK_SERVICENAME_extra7121="glue"
CHECK_RISK_extra7121='If not enabled sensitive information at rest is not protected.'
CHECK_REMEDIATION_extra7121='Enable Encryption in the Security configurations.'
CHECK_DOC_extra7121='https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html'
CHECK_CAF_EPIC_extra7121='Data Protection'
extra7121(){
for regx in $REGIONS; do
LIST_EP_SC=$($AWSCLI glue get-dev-endpoints $PROFILE_OPT --region $regx --query 'DevEndpoints[*].{Name:EndpointName,Security:SecurityConfiguration}' --output json 2>&1)
if [[ $(echo "$LIST_EP_SC" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get dev endpoints" "$regx"
continue
fi
if [[ $LIST_EP_SC != '[]' ]]; then
for ep in $(echo "${LIST_EP_SC}"| jq -r '.[] | @base64');do
ENDPOINT_NAME=$(echo $ep | base64 --decode | jq -r '.Name')
ENDPOINT_SC=$(echo $ep | base64 --decode | jq -r '.Security // empty')
if [[ ! -z "$ENDPOINT_SC" ]]; then
ENDPOINT_SC_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${ENDPOINT_SC}" $PROFILE_OPT --region $regx --query 'SecurityConfiguration.EncryptionConfiguration.JobBookmarksEncryption.JobBookmarksEncryptionMode' --output text)
if [[ "$ENDPOINT_SC_ENCRYPTION" == "DISABLED" ]]; then
textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have Job Bookmark encryption enabled!" "$regx" "$ENDPOINT_NAME"
else
textPass "$regx: Glue development endpoint $ENDPOINT_NAME has Job Bookmark encryption enabled" "$regx" "$ENDPOINT_NAME"
fi
else
textFail "$regx: Glue development endpoint $ENDPOINT_NAME does not have security configuration" "$regx" "$ENDPOINT_NAME"
fi
done
else
textInfo "$regx: There are no Glue development endpoints" "$regx"
fi
done
}

View File

@@ -1,52 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7122="7.122"
CHECK_TITLE_extra7122="[extra7122] Check if Glue ETL Jobs have Job bookmark encryption enabled."
CHECK_SCORED_extra7122="NOT_SCORED"
CHECK_CIS_LEVEL_extra7122="EXTRA"
CHECK_SEVERITY_extra7122="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra7122="AwsGlue"
CHECK_ALTERNATE_check7122="extra7122"
CHECK_SERVICENAME_extra7122="glue"
CHECK_RISK_extra7122='If not enabled sensitive information at rest is not protected.'
CHECK_REMEDIATION_extra7122='Enable Encryption in the Security configurations.'
CHECK_DOC_extra7122='https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html'
CHECK_CAF_EPIC_extra7122='Data Protection'
extra7122(){
for regx in $REGIONS; do
JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}' 2>&1)
if [[ $(echo "$JOB_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to get jobs" "$regx"
continue
fi
if [[ $JOB_LIST != '[]' ]]; then
for job in $(echo "${JOB_LIST}" | jq -r '.[] | @base64'); do
JOB_NAME=$(echo $job | base64 --decode | jq -r '.Name')
SECURITY_CONFIGURATION=$(echo $job | base64 --decode | jq -r '.SecurityConfiguration // empty')
if [[ ! -z "$SECURITY_CONFIGURATION" ]]; then
JOB_BOOKMARK_ENCRYPTION=$($AWSCLI glue get-security-configuration --name "${SECURITY_CONFIGURATION}" $PROFILE_OPT --region $regx --output text --query 'SecurityConfiguration.EncryptionConfiguration.JobBookmarksEncryption.JobBookmarksEncryptionMode')
if [[ "$JOB_BOOKMARK_ENCRYPTION" == "DISABLED" ]]; then
textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" "$JOB_NAME"
else
textPass "$regx: Glue job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION for Job bookmark encryption enabled" "$regx" "$JOB_NAME"
fi
else
textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" "$JOB_NAME"
fi
done
else
textInfo "$regx: There are no Glue jobs" "$regx"
fi
done
}

View File

@@ -0,0 +1,4 @@
from providers.aws.lib.audit_info.audit_info import current_audit_info
from providers.aws.services.glue.glue_service import Glue
glue_client = Glue(current_audit_info)

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_data_catalogs_connection_passwords_encryption_enabled",
"CheckTitle": "Check if Glue data catalog settings have encrypt connection password enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue data catalog settings have encrypt connection password enabled.",
"Risk": "If not enabled sensitive information at rest is not protected.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "aws glue put-data-catalog-encryption-settings --data-catalog-encryption-settings ConnectionPasswordEncryption={ReturnConnectionPasswordEncrypted=True,AwsKmsKeyId=<ksm_key_arn>",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_37#cloudformation",
"Other": "",
"Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_37#terraform"
},
"Recommendation": {
"Text": "On the AWS Glue console; you can enable this option on the Data catalog settings page.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/encrypt-connection-passwords.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Data Protection",
"Compliance": []
}

View File

@@ -0,0 +1,20 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_data_catalogs_connection_passwords_encryption_enabled(Check):
def execute(self):
findings = []
for encryption in glue_client.catalog_encryption_settings:
report = Check_Report(self.metadata)
report.resource_id = glue_client.audited_account
report.region = encryption.region
report.status = "FAIL"
report.status_extended = (
"Glue data catalog connection password is not encrypted."
)
if encryption.password_encryption:
report.status = "PASS"
report.status_extended = f"Glue data catalog connection password is encrypted with KMS key {encryption.password_kms_id}."
findings.append(report)
return findings

View File

@@ -0,0 +1,91 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import CatalogEncryptionSetting
AWS_REGION = "us-east-1"
class Test_glue_data_catalogs_connection_passwords_encryption_enabled:
def test_glue_no_settings(self):
glue_client = mock.MagicMock
glue_client.catalog_encryption_settings = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_data_catalogs_connection_passwords_encryption_enabled.glue_data_catalogs_connection_passwords_encryption_enabled import (
glue_data_catalogs_connection_passwords_encryption_enabled,
)
check = glue_data_catalogs_connection_passwords_encryption_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_catalog_password_unencrypted(self):
glue_client = mock.MagicMock
glue_client.catalog_encryption_settings = [
CatalogEncryptionSetting(
mode="DISABLED",
kms_id=None,
region=AWS_REGION,
password_encryption=False,
password_kms_id=None,
)
]
glue_client.audited_account = "12345678912"
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_data_catalogs_connection_passwords_encryption_enabled.glue_data_catalogs_connection_passwords_encryption_enabled import (
glue_data_catalogs_connection_passwords_encryption_enabled,
)
check = glue_data_catalogs_connection_passwords_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"Glue data catalog connection password is not encrypted",
result[0].status_extended,
)
assert result[0].resource_id == "12345678912"
def test_glue_catalog_encrypted(self):
glue_client = mock.MagicMock
glue_client.catalog_encryption_settings = [
CatalogEncryptionSetting(
mode="DISABLED",
region=AWS_REGION,
password_encryption=True,
password_kms_id="kms-key",
)
]
glue_client.audited_account = "12345678912"
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_data_catalogs_connection_passwords_encryption_enabled.glue_data_catalogs_connection_passwords_encryption_enabled import (
glue_data_catalogs_connection_passwords_encryption_enabled,
)
check = glue_data_catalogs_connection_passwords_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"Glue data catalog connection password is encrypted",
result[0].status_extended,
)
assert result[0].resource_id == "12345678912"

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_data_catalogs_metadata_encryption_enabled",
"CheckTitle": "Check if Glue data catalog settings have metadata encryption enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue data catalog settings have metadata encryption enabled.",
"Risk": "If not enabled sensitive information at rest is not protected.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "aws glue put-data-catalog-encryption-settings --data-catalog-encryption-settings EncryptionAtRest={CatalogEncryptionMode=SSE-KMS,SseAwsKmsKeyId=<ksm_key_arn>",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_37#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/data-catalog-encryption-at-rest.html",
"Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_37#terraform"
},
"Recommendation": {
"Text": "Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/encrypt-glue-data-catalog.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Data Protection",
"Compliance": []
}

View File

@@ -0,0 +1,20 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_data_catalogs_metadata_encryption_enabled(Check):
def execute(self):
findings = []
for encryption in glue_client.catalog_encryption_settings:
report = Check_Report(self.metadata)
report.resource_id = glue_client.audited_account
report.region = encryption.region
report.status = "FAIL"
report.status_extended = (
"Glue data catalog settings have metadata encryption disabled."
)
if encryption.mode == "SSE-KMS":
report.status = "PASS"
report.status_extended = f"Glue data catalog settings have metadata encryption enabled with KMS key {encryption.kms_id}."
findings.append(report)
return findings

View File

@@ -0,0 +1,92 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import CatalogEncryptionSetting
AWS_REGION = "us-east-1"
class Test_glue_data_catalogs_metadata_encryption_enabled:
def test_glue_no_settings(self):
glue_client = mock.MagicMock
glue_client.catalog_encryption_settings = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_data_catalogs_metadata_encryption_enabled.glue_data_catalogs_metadata_encryption_enabled import (
glue_data_catalogs_metadata_encryption_enabled,
)
check = glue_data_catalogs_metadata_encryption_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_catalog_unencrypted(self):
glue_client = mock.MagicMock
glue_client.catalog_encryption_settings = [
CatalogEncryptionSetting(
mode="DISABLED",
kms_id=None,
region=AWS_REGION,
password_encryption=False,
password_kms_id=None,
)
]
glue_client.audited_account = "12345678912"
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_data_catalogs_metadata_encryption_enabled.glue_data_catalogs_metadata_encryption_enabled import (
glue_data_catalogs_metadata_encryption_enabled,
)
check = glue_data_catalogs_metadata_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"Glue data catalog settings have metadata encryption disabled",
result[0].status_extended,
)
assert result[0].resource_id == "12345678912"
def test_glue_catalog_encrypted(self):
glue_client = mock.MagicMock
glue_client.catalog_encryption_settings = [
CatalogEncryptionSetting(
mode="SSE-KMS",
kms_id="kms-key",
region=AWS_REGION,
password_encryption=False,
password_kms_id=None,
)
]
glue_client.audited_account = "12345678912"
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_data_catalogs_metadata_encryption_enabled.glue_data_catalogs_metadata_encryption_enabled import (
glue_data_catalogs_metadata_encryption_enabled,
)
check = glue_data_catalogs_metadata_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"Glue data catalog settings have metadata encryption enabled",
result[0].status_extended,
)
assert result[0].resource_id == "12345678912"

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_database_connections_ssl_enabled",
"CheckTitle": "Check if Glue database connection has SSL connection enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue database connection has SSL connection enabled.",
"Risk": "Data exfiltration could happen if information is not protected in transit.",
"RelatedUrl": "https://docs.aws.amazon.com/glue/latest/dg/encryption-in-transit.html",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Configure encryption settings for crawlers, ETL jobs and development endpoints using security configurations in AWS Glue.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/encryption-in-transit.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Data Protection",
"Compliance": []
}

View File

@@ -0,0 +1,22 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_database_connections_ssl_enabled(Check):
def execute(self):
findings = []
for conn in glue_client.connections:
report = Check_Report(self.metadata)
report.resource_id = conn.name
report.region = conn.region
report.status = "FAIL"
report.status_extended = (
f"Glue connection {conn.name} has SSL connection disabled."
)
if conn.properties.get("JDBC_ENFORCE_SSL") == "true":
report.status = "PASS"
report.status_extended = (
f"Glue connection {conn.name} has SSL connection enabled."
)
findings.append(report)
return findings

View File

@@ -0,0 +1,99 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import Connection
AWS_REGION = "us-east-1"
class Test_glue_database_connections_ssl_enabled:
def test_glue_no_conns(self):
glue_client = mock.MagicMock
glue_client.connections = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_database_connections_ssl_enabled.glue_database_connections_ssl_enabled import (
glue_database_connections_ssl_enabled,
)
check = glue_database_connections_ssl_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_table_no_SSL(self):
glue_client = mock.MagicMock
glue_client.connections = [
Connection(
name="test",
type="JDBC",
properties={
"CONNECTOR_TYPE": "Jdbc",
"JDBC_CONNECTION_URL": '[["default=test"],":"]',
"CONNECTOR_URL": "s3://bck-dev",
"CONNECTOR_CLASS_NAME": "test",
},
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_database_connections_ssl_enabled.glue_database_connections_ssl_enabled import (
glue_database_connections_ssl_enabled,
)
check = glue_database_connections_ssl_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"has SSL connection disabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_table_with_SSL(self):
glue_client = mock.MagicMock
glue_client.connections = [
Connection(
name="test",
type="JDBC",
properties={
"CONNECTOR_TYPE": "Jdbc",
"JDBC_CONNECTION_URL": '[["default=test"],":"]',
"CONNECTOR_URL": "s3://bck-dev",
"CONNECTOR_CLASS_NAME": "test",
"JDBC_ENFORCE_SSL": "true",
},
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_database_connections_ssl_enabled.glue_database_connections_ssl_enabled import (
glue_database_connections_ssl_enabled,
)
check = glue_database_connections_ssl_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has SSL connection enabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_development_endpoints_cloudwatch_logs_encryption_enabled",
"CheckTitle": "Check if Glue development endpoints have CloudWatch logs encryption enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue development endpoints have CloudWatch logs encryption enabled.",
"Risk": "If not enabled sensitive information at rest is not protected.",
"RelatedUrl": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html",
"Remediation": {
"Code": {
"CLI": "aws glue create-security-configuration --name cw-encrypted-sec-config --encryption-configuration {'CloudWatchEncryption': [{'CloudWatchEncryptionMode': 'SSE-KMS','KmsKeyArn': <kms_arn>}]}",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/cloud-watch-logs-encryption-enabled.html",
"Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform"
},
"Recommendation": {
"Text": "Enable Encryption in the Security configurations.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Data Protection",
"Compliance": []
}

View File

@@ -0,0 +1,25 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_development_endpoints_cloudwatch_logs_encryption_enabled(Check):
def execute(self):
findings = []
for endpoint in glue_client.dev_endpoints:
no_sec_configs = True
report = Check_Report(self.metadata)
report.resource_id = endpoint.name
report.region = endpoint.region
for sec_config in glue_client.security_configs:
if sec_config.name == endpoint.security:
no_sec_configs = False
report.status = "FAIL"
report.status_extended = f"Glue development endpoint {endpoint.name} does not have CloudWatch logs encryption enabled."
if sec_config.cw_encryption != "DISABLED":
report.status = "PASS"
report.status_extended = f"Glue development endpoint {endpoint.name} has CloudWatch logs encryption enabled with key {sec_config.cw_key_arn}."
if no_sec_configs:
report.status = "FAIL"
report.status_extended = f"Glue development endpoint {endpoint.name} does not have security configuration."
findings.append(report)
return findings

View File

@@ -0,0 +1,136 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import DevEndpoint, SecurityConfig
AWS_REGION = "us-east-1"
class Test_glue_development_endpoints_cloudwatch_logs_encryption_enabled:
def test_glue_no_endpoints(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_cloudwatch_logs_encryption_enabled.glue_development_endpoints_cloudwatch_logs_encryption_enabled import (
glue_development_endpoints_cloudwatch_logs_encryption_enabled,
)
check = glue_development_endpoints_cloudwatch_logs_encryption_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_encrypted_endpoint(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
cw_encryption="SSE-KMS",
cw_key_arn="key_arn",
s3_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_cloudwatch_logs_encryption_enabled.glue_development_endpoints_cloudwatch_logs_encryption_enabled import (
glue_development_endpoints_cloudwatch_logs_encryption_enabled,
)
check = glue_development_endpoints_cloudwatch_logs_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has CloudWatch logs encryption enabled with key",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_unencrypted_endpoint(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
s3_encryption="DISABLED",
cw_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_cloudwatch_logs_encryption_enabled.glue_development_endpoints_cloudwatch_logs_encryption_enabled import (
glue_development_endpoints_cloudwatch_logs_encryption_enabled,
)
check = glue_development_endpoints_cloudwatch_logs_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have CloudWatch logs encryption enabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_no_sec_configs(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_cloudwatch_logs_encryption_enabled.glue_development_endpoints_cloudwatch_logs_encryption_enabled import (
glue_development_endpoints_cloudwatch_logs_encryption_enabled,
)
check = glue_development_endpoints_cloudwatch_logs_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have security configuration",
result[0].status_extended,
)
assert result[0].resource_id == "test"

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_development_endpoints_job_bookmark_encryption_enabled",
"CheckTitle": "Check if Glue development endpoints have Job bookmark encryption enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue development endpoints have Job bookmark encryption enabled.",
"Risk": "If not enabled sensitive information at rest is not protected.",
"RelatedUrl": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html",
"Remediation": {
"Code": {
"CLI": "aws glue create-security-configuration --name jb-encrypted-sec-config --encryption-configuration {'JobBookmarksEncryption': [{'JobBookmarksEncryptionMode': 'SSE-KMS','KmsKeyArn': <kms_arn>}]}",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/job-bookmark-encryption-enabled.html",
"Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform"
},
"Recommendation": {
"Text": "Enable Encryption in the Security configurations.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Data Protection",
"Compliance": []
}

View File

@@ -0,0 +1,25 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_development_endpoints_job_bookmark_encryption_enabled(Check):
def execute(self):
findings = []
for endpoint in glue_client.dev_endpoints:
no_sec_configs = True
report = Check_Report(self.metadata)
report.resource_id = endpoint.name
report.region = endpoint.region
for sec_config in glue_client.security_configs:
if sec_config.name == endpoint.security:
no_sec_configs = False
report.status = "FAIL"
report.status_extended = f"Glue development endpoint {endpoint.name} does not have Job Bookmark encryption enabled."
if sec_config.jb_encryption != "DISABLED":
report.status = "PASS"
report.status_extended = f"Glue development endpoint {endpoint.name} has Job Bookmark encryption enabled with key {sec_config.jb_key_arn}."
if no_sec_configs:
report.status = "FAIL"
report.status_extended = f"Glue development endpoint {endpoint.name} does not have security configuration."
findings.append(report)
return findings

View File

@@ -0,0 +1,136 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import DevEndpoint, SecurityConfig
AWS_REGION = "us-east-1"
class Test_glue_development_endpoints_job_bookmark_encryption_enabled:
def test_glue_no_endpoints(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_job_bookmark_encryption_enabled.glue_development_endpoints_job_bookmark_encryption_enabled import (
glue_development_endpoints_job_bookmark_encryption_enabled,
)
check = glue_development_endpoints_job_bookmark_encryption_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_encrypted_endpoint(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
jb_encryption="SSE-KMS",
jb_key_arn="key_arn",
cw_encryption="DISABLED",
s3_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_job_bookmark_encryption_enabled.glue_development_endpoints_job_bookmark_encryption_enabled import (
glue_development_endpoints_job_bookmark_encryption_enabled,
)
check = glue_development_endpoints_job_bookmark_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has Job Bookmark encryption enabled with key",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_unencrypted_endpoint(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
s3_encryption="DISABLED",
cw_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_job_bookmark_encryption_enabled.glue_development_endpoints_job_bookmark_encryption_enabled import (
glue_development_endpoints_job_bookmark_encryption_enabled,
)
check = glue_development_endpoints_job_bookmark_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have Job Bookmark encryption enabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_no_sec_configs(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_job_bookmark_encryption_enabled.glue_development_endpoints_job_bookmark_encryption_enabled import (
glue_development_endpoints_job_bookmark_encryption_enabled,
)
check = glue_development_endpoints_job_bookmark_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have security configuration",
result[0].status_extended,
)
assert result[0].resource_id == "test"

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_development_endpoints_s3_encryption_enabled",
"CheckTitle": "Check if Glue development endpoints have S3 encryption enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue development endpoints have S3 encryption enabled.",
"Risk": "Data exfiltration could happen if information is not protected. KMS keys provide additional security level to IAM policies.",
"RelatedUrl": "https://docs.aws.amazon.com/glue/latest/dg/encryption-security-configuration.html",
"Remediation": {
"Code": {
"CLI": "aws glue create-security-configuration --name s3-encrypted-sec-config --encryption-configuration {'S3Encryption': [{'S3EncryptionMode': 'SSE-KMS','KmsKeyArn': <kms_arn>}]}",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/s3-encryption-enabled.html",
"Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform"
},
"Recommendation": {
"Text": "Specify AWS KMS keys to use for input and output from S3 and EBS.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/encryption-security-configuration.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Data Protection",
"Compliance": []
}

View File

@@ -0,0 +1,25 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_development_endpoints_s3_encryption_enabled(Check):
def execute(self):
findings = []
for endpoint in glue_client.dev_endpoints:
no_sec_configs = True
report = Check_Report(self.metadata)
report.resource_id = endpoint.name
report.region = endpoint.region
for sec_config in glue_client.security_configs:
if sec_config.name == endpoint.security:
no_sec_configs = False
report.status = "FAIL"
report.status_extended = f"Glue development endpoint {endpoint.name} does not have S3 encryption enabled."
if sec_config.s3_encryption != "DISABLED":
report.status = "PASS"
report.status_extended = f"Glue development endpoint {endpoint.name} has S3 encryption enabled with key {sec_config.s3_key_arn}."
if no_sec_configs:
report.status = "FAIL"
report.status_extended = f"Glue development endpoint {endpoint.name} does not have security configuration."
findings.append(report)
return findings

View File

@@ -0,0 +1,136 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import DevEndpoint, SecurityConfig
AWS_REGION = "us-east-1"
class Test_glue_development_endpoints_s3_encryption_enabled:
def test_glue_no_endpoints(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_s3_encryption_enabled.glue_development_endpoints_s3_encryption_enabled import (
glue_development_endpoints_s3_encryption_enabled,
)
check = glue_development_endpoints_s3_encryption_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_encrypted_endpoint(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
s3_encryption="SSE-KMS",
s3_key_arn="key_arn",
cw_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_s3_encryption_enabled.glue_development_endpoints_s3_encryption_enabled import (
glue_development_endpoints_s3_encryption_enabled,
)
check = glue_development_endpoints_s3_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has S3 encryption enabled with key",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_unencrypted_endpoint(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
s3_encryption="DISABLED",
cw_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_s3_encryption_enabled.glue_development_endpoints_s3_encryption_enabled import (
glue_development_endpoints_s3_encryption_enabled,
)
check = glue_development_endpoints_s3_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have S3 encryption enabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_no_sec_configs(self):
glue_client = mock.MagicMock
glue_client.dev_endpoints = [
DevEndpoint(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_development_endpoints_s3_encryption_enabled.glue_development_endpoints_s3_encryption_enabled import (
glue_development_endpoints_s3_encryption_enabled,
)
check = glue_development_endpoints_s3_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have security configuration",
result[0].status_extended,
)
assert result[0].resource_id == "test"

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_development_endpoints_s3_encryption_enabled",
"CheckTitle": "Check if Glue ETL Jobs have S3 encryption enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue ETL Jobs have S3 encryption enabled.",
"Risk": "If not enabled sensitive information at rest is not protected.",
"RelatedUrl": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html",
"Remediation": {
"Code": {
"CLI": "aws glue create-security-configuration --name s3-encrypted-sec-config --encryption-configuration {'S3Encryption': [{'S3EncryptionMode': 'SSE-KMS','KmsKeyArn': <kms_arn>}]}",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/s3-encryption-enabled.html",
"Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform"
},
"Recommendation": {
"Text": "Provide the encryption properties that are used by crawlers, jobs and development endpoints.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Data Protection",
"Compliance": []
}

View File

@@ -0,0 +1,35 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_etl_jobs_amazon_s3_encryption_enabled(Check):
def execute(self):
findings = []
for job in glue_client.jobs:
no_sec_configs = True
report = Check_Report(self.metadata)
report.resource_id = job.name
report.region = job.region
for sec_config in glue_client.security_configs:
if sec_config.name == job.security:
no_sec_configs = False
report.status = "FAIL"
report.status_extended = (
f"Glue job {job.name} does not have S3 encryption enabled."
)
if sec_config.s3_encryption != "DISABLED":
report.status = "PASS"
report.status_extended = f"Glue job {job.name} has S3 encryption enabled with key {sec_config.s3_key_arn}."
if no_sec_configs:
if job.arguments and job.arguments.get("--encryption-type") == "sse-s3":
report.status = "PASS"
report.status_extended = (
f"Glue job {job.name} has S3 encryption enabled."
)
else:
report.status = "FAIL"
report.status_extended = (
f"Glue job {job.name} does not have security configuration."
)
findings.append(report)
return findings

View File

@@ -0,0 +1,173 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import Job, SecurityConfig
AWS_REGION = "us-east-1"
class Test_glue_etl_jobs_amazon_s3_encryption_enabled:
def test_glue_no_jobs(self):
glue_client = mock.MagicMock
glue_client.jobs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_amazon_s3_encryption_enabled.glue_etl_jobs_amazon_s3_encryption_enabled import (
glue_etl_jobs_amazon_s3_encryption_enabled,
)
check = glue_etl_jobs_amazon_s3_encryption_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_encrypted_job(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
arguments=None,
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
s3_encryption="SSE-KMS",
s3_key_arn="key_arn",
cw_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_amazon_s3_encryption_enabled.glue_etl_jobs_amazon_s3_encryption_enabled import (
glue_etl_jobs_amazon_s3_encryption_enabled,
)
check = glue_etl_jobs_amazon_s3_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has S3 encryption enabled with key",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_unencrypted_job(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
arguments=None,
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
s3_encryption="DISABLED",
cw_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_amazon_s3_encryption_enabled.glue_etl_jobs_amazon_s3_encryption_enabled import (
glue_etl_jobs_amazon_s3_encryption_enabled,
)
check = glue_etl_jobs_amazon_s3_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have S3 encryption enabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_no_sec_configs(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_amazon_s3_encryption_enabled.glue_etl_jobs_amazon_s3_encryption_enabled import (
glue_etl_jobs_amazon_s3_encryption_enabled,
)
check = glue_etl_jobs_amazon_s3_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have security configuration",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_encrypted_job_with_argument(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
arguments={
"--encryption-type": "sse-s3",
"--enable-job-insights": "false",
},
region=AWS_REGION,
)
]
glue_client.security_configs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_amazon_s3_encryption_enabled.glue_etl_jobs_amazon_s3_encryption_enabled import (
glue_etl_jobs_amazon_s3_encryption_enabled,
)
check = glue_etl_jobs_amazon_s3_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has S3 encryption enabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_etl_jobs_cloudwatch_logs_encryption_enabled",
"CheckTitle": "Check if Glue ETL Jobs have CloudWatch Logs encryption enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue ETL Jobs have CloudWatch Logs encryption enabled.",
"Risk": "If not enabled sensitive information at rest is not protected.",
"RelatedUrl": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html",
"Remediation": {
"Code": {
"CLI": "aws glue create-security-configuration --name cw-encrypted-sec-config --encryption-configuration {'CloudWatchEncryption': [{'CloudWatchEncryptionMode': 'SSE-KMS','KmsKeyArn': <kms_arn>}]}",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/cloud-watch-logs-encryption-enabled.html",
"Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform"
},
"Recommendation": {
"Text": "Enable Encryption in the Security configurations.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Logging and Monitoring",
"Compliance": []
}

View File

@@ -0,0 +1,27 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_etl_jobs_cloudwatch_logs_encryption_enabled(Check):
def execute(self):
findings = []
for job in glue_client.jobs:
no_sec_configs = True
report = Check_Report(self.metadata)
report.resource_id = job.name
report.region = job.region
for sec_config in glue_client.security_configs:
if sec_config.name == job.security:
no_sec_configs = False
report.status = "FAIL"
report.status_extended = f"Glue job {job.name} does not have CloudWatch Logs encryption enabled."
if sec_config.cw_encryption != "DISABLED":
report.status = "PASS"
report.status_extended = f"Glue job {job.name} has CloudWatch Logs encryption enabled with key {sec_config.cw_key_arn}."
if no_sec_configs:
report.status = "FAIL"
report.status_extended = (
f"Glue job {job.name} does not have security configuration."
)
findings.append(report)
return findings

View File

@@ -0,0 +1,138 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import Job, SecurityConfig
AWS_REGION = "us-east-1"
class Test_glue_etl_jobs_cloudwatch_logs_encryption_enabled:
def test_glue_no_jobs(self):
glue_client = mock.MagicMock
glue_client.jobs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_cloudwatch_logs_encryption_enabled.glue_etl_jobs_cloudwatch_logs_encryption_enabled import (
glue_etl_jobs_cloudwatch_logs_encryption_enabled,
)
check = glue_etl_jobs_cloudwatch_logs_encryption_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_encrypted_job(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
arguments=None,
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
cw_encryption="SSE-KMS",
cw_key_arn="key_arn",
s3_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_cloudwatch_logs_encryption_enabled.glue_etl_jobs_cloudwatch_logs_encryption_enabled import (
glue_etl_jobs_cloudwatch_logs_encryption_enabled,
)
check = glue_etl_jobs_cloudwatch_logs_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has CloudWatch Logs encryption enabled with key",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_unencrypted_job(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
arguments=None,
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
s3_encryption="DISABLED",
cw_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_cloudwatch_logs_encryption_enabled.glue_etl_jobs_cloudwatch_logs_encryption_enabled import (
glue_etl_jobs_cloudwatch_logs_encryption_enabled,
)
check = glue_etl_jobs_cloudwatch_logs_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have CloudWatch Logs encryption enabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_no_sec_configs(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_cloudwatch_logs_encryption_enabled.glue_etl_jobs_cloudwatch_logs_encryption_enabled import (
glue_etl_jobs_cloudwatch_logs_encryption_enabled,
)
check = glue_etl_jobs_cloudwatch_logs_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have security configuration",
result[0].status_extended,
)
assert result[0].resource_id == "test"

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "glue_etl_jobs_job_bookmark_encryption_enabled",
"CheckTitle": "Check if Glue ETL Jobs have Job bookmark encryption enabled.",
"CheckType": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"],
"ServiceName": "glue",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:glue:region:account-id:certificate/resource-id",
"Severity": "medium",
"ResourceType": "AwsGlue",
"Description": "Check if Glue ETL Jobs have Job bookmark encryption enabled.",
"Risk": "If not enabled sensitive information at rest is not protected.",
"RelatedUrl": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html",
"Remediation": {
"Code": {
"CLI": "aws glue create-security-configuration --name jb-encrypted-sec-config --encryption-configuration {'JobBookmarksEncryption': [{'JobBookmarksEncryptionMode': 'SSE-KMS','KmsKeyArn': <kms_arn>}]}",
"NativeIaC": "https://docs.bridgecrew.io/docs/bc_aws_general_41#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Glue/job-bookmark-encryption-enabled.html",
"Terraform": "https://docs.bridgecrew.io/docs/bc_aws_general_41#terraform"
},
"Recommendation": {
"Text": "Enable Encryption in the Security configurations.",
"Url": "https://docs.aws.amazon.com/glue/latest/dg/console-security-configurations.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Logging and Monitoring",
"Compliance": []
}

View File

@@ -0,0 +1,27 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.glue.glue_client import glue_client
class glue_etl_jobs_job_bookmark_encryption_enabled(Check):
def execute(self):
findings = []
for job in glue_client.jobs:
no_sec_configs = True
report = Check_Report(self.metadata)
report.resource_id = job.name
report.region = job.region
for sec_config in glue_client.security_configs:
if sec_config.name == job.security:
no_sec_configs = False
report.status = "FAIL"
report.status_extended = f"Glue job {job.name} does not have Job bookmark encryption enabled."
if sec_config.jb_encryption != "DISABLED":
report.status = "PASS"
report.status_extended = f"Glue job {job.name} has Job bookmark encryption enabled with key {sec_config.jb_key_arn}."
if no_sec_configs:
report.status = "FAIL"
report.status_extended = (
f"Glue job {job.name} does not have security configuration."
)
findings.append(report)
return findings

View File

@@ -0,0 +1,138 @@
from re import search
from unittest import mock
from providers.aws.services.glue.glue_service import Job, SecurityConfig
AWS_REGION = "us-east-1"
class Test_glue_etl_jobs_job_bookmark_encryption_enabled:
def test_glue_no_jobs(self):
glue_client = mock.MagicMock
glue_client.jobs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_job_bookmark_encryption_enabled.glue_etl_jobs_job_bookmark_encryption_enabled import (
glue_etl_jobs_job_bookmark_encryption_enabled,
)
check = glue_etl_jobs_job_bookmark_encryption_enabled()
result = check.execute()
assert len(result) == 0
def test_glue_encrypted_job(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
arguments=None,
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
jb_encryption="SSE-KMS",
jb_key_arn="key_arn",
s3_encryption="DISABLED",
cw_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_job_bookmark_encryption_enabled.glue_etl_jobs_job_bookmark_encryption_enabled import (
glue_etl_jobs_job_bookmark_encryption_enabled,
)
check = glue_etl_jobs_job_bookmark_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"has Job bookmark encryption enabled with key",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_unencrypted_job(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
arguments=None,
region=AWS_REGION,
)
]
glue_client.security_configs = [
SecurityConfig(
name="sec_config",
s3_encryption="DISABLED",
cw_encryption="DISABLED",
jb_encryption="DISABLED",
region=AWS_REGION,
)
]
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_job_bookmark_encryption_enabled.glue_etl_jobs_job_bookmark_encryption_enabled import (
glue_etl_jobs_job_bookmark_encryption_enabled,
)
check = glue_etl_jobs_job_bookmark_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have Job bookmark encryption enabled",
result[0].status_extended,
)
assert result[0].resource_id == "test"
def test_glue_no_sec_configs(self):
glue_client = mock.MagicMock
glue_client.jobs = [
Job(
name="test",
security="sec_config",
region=AWS_REGION,
)
]
glue_client.security_configs = []
with mock.patch(
"providers.aws.services.glue.glue_service.Glue",
glue_client,
):
# Test Check
from providers.aws.services.glue.glue_etl_jobs_job_bookmark_encryption_enabled.glue_etl_jobs_job_bookmark_encryption_enabled import (
glue_etl_jobs_job_bookmark_encryption_enabled,
)
check = glue_etl_jobs_job_bookmark_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"does not have security configuration",
result[0].status_extended,
)
assert result[0].resource_id == "test"

View File

@@ -0,0 +1,222 @@
import threading
from typing import Optional
from pydantic import BaseModel
from lib.logger import logger
from providers.aws.aws_provider import generate_regional_clients
################## Glue
class Glue:
def __init__(self, audit_info):
self.service = "glue"
self.session = audit_info.audit_session
self.audited_account = audit_info.audited_account
self.regional_clients = generate_regional_clients(self.service, audit_info)
self.connections = []
self.__threading_call__(self.__get_connections__)
self.tables = []
self.__threading_call__(self.__search_tables__)
self.catalog_encryption_settings = []
self.__threading_call__(self.__get_data_catalog_encryption_settings__)
self.dev_endpoints = []
self.__threading_call__(self.__get_dev_endpoints__)
self.security_configs = []
self.__threading_call__(self.__get_security_configurations__)
self.jobs = []
self.__threading_call__(self.__get_jobs__)
def __get_session__(self):
return self.session
def __threading_call__(self, call):
threads = []
for regional_client in self.regional_clients.values():
threads.append(threading.Thread(target=call, args=(regional_client,)))
for t in threads:
t.start()
for t in threads:
t.join()
def __get_connections__(self, regional_client):
logger.info("Glue - Getting connections...")
try:
get_connections_paginator = regional_client.get_paginator("get_connections")
for page in get_connections_paginator.paginate():
for conn in page["ConnectionList"]:
self.connections.append(
Connection(
name=conn["Name"],
type=conn["ConnectionType"],
properties=conn["ConnectionProperties"],
region=regional_client.region,
)
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __get_dev_endpoints__(self, regional_client):
logger.info("Glue - Getting dev endpoints...")
try:
get_dev_endpoints_paginator = regional_client.get_paginator(
"get_dev_endpoints"
)
for page in get_dev_endpoints_paginator.paginate():
for endpoint in page["DevEndpoints"]:
self.dev_endpoints.append(
DevEndpoint(
name=endpoint["EndpointName"],
security=endpoint.get("SecurityConfiguration"),
region=regional_client.region,
)
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __get_jobs__(self, regional_client):
logger.info("Glue - Getting jobs...")
try:
get_jobs_paginator = regional_client.get_paginator("get_jobs")
for page in get_jobs_paginator.paginate():
for job in page["Jobs"]:
self.jobs.append(
Job(
name=job["Name"],
security=job.get("SecurityConfiguration"),
arguments=job.get("DefaultArguments"),
region=regional_client.region,
)
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __get_security_configurations__(self, regional_client):
logger.info("Glue - Getting security configs...")
try:
get_security_configurations_paginator = regional_client.get_paginator(
"get_security_configurations"
)
for page in get_security_configurations_paginator.paginate():
for config in page["SecurityConfigurations"]:
self.security_configs.append(
SecurityConfig(
name=config["Name"],
s3_encryption=config["EncryptionConfiguration"][
"S3Encryption"
][0]["S3EncryptionMode"],
s3_key_arn=config["EncryptionConfiguration"][
"S3Encryption"
][0].get("KmsKeyArn"),
cw_encryption=config["EncryptionConfiguration"][
"CloudWatchEncryption"
]["CloudWatchEncryptionMode"],
cw_key_arn=config["EncryptionConfiguration"][
"CloudWatchEncryption"
].get("KmsKeyArn"),
jb_encryption=config["EncryptionConfiguration"][
"JobBookmarksEncryption"
]["JobBookmarksEncryptionMode"],
jb_key_arn=config["EncryptionConfiguration"][
"JobBookmarksEncryption"
].get("KmsKeyArn"),
region=regional_client.region,
)
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __search_tables__(self, regional_client):
logger.info("Glue - Search Tables...")
try:
for table in regional_client.search_tables()["TableList"]:
self.tables.append(
Table(
name=table["Name"],
database=table["DatabaseName"],
catalog=table["CatalogId"],
region=regional_client.region,
)
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __get_data_catalog_encryption_settings__(self, regional_client):
logger.info("Glue - Catalog Encryption Settings...")
try:
settings = regional_client.get_data_catalog_encryption_settings()[
"DataCatalogEncryptionSettings"
]
self.catalog_encryption_settings.append(
CatalogEncryptionSetting(
mode=settings["EncryptionAtRest"]["CatalogEncryptionMode"],
kms_id=settings["EncryptionAtRest"].get("SseAwsKmsKeyId"),
password_encryption=settings["ConnectionPasswordEncryption"][
"ReturnConnectionPasswordEncrypted"
],
password_kms_id=settings["ConnectionPasswordEncryption"].get(
"AwsKmsKeyId"
),
region=regional_client.region,
)
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
class Connection(BaseModel):
name: str
type: str
properties: dict
region: str
class Table(BaseModel):
name: str
database: str
catalog: Optional[str]
region: str
class CatalogEncryptionSetting(BaseModel):
mode: str
kms_id: Optional[str]
password_encryption: bool
password_kms_id: Optional[str]
region: str
class DevEndpoint(BaseModel):
name: str
security: Optional[str]
region: str
class Job(BaseModel):
name: str
security: Optional[str]
arguments: Optional[dict]
region: str
class SecurityConfig(BaseModel):
name: str
s3_encryption: str
s3_key_arn: Optional[str]
cw_encryption: str
cw_key_arn: Optional[str]
jb_encryption: str
jb_key_arn: Optional[str]
region: str

View File

@@ -0,0 +1,248 @@
from unittest.mock import patch
import botocore
from boto3 import session
from moto import mock_glue
from providers.aws.lib.audit_info.models import AWS_Audit_Info
from providers.aws.services.glue.glue_service import Glue
AWS_ACCOUNT_NUMBER = 123456789012
AWS_REGION = "us-east-1"
# Mocking Access Analyzer Calls
make_api_call = botocore.client.BaseClient._make_api_call
def mock_make_api_call(self, operation_name, kwarg):
"""
We have to mock every AWS API call using Boto3
As you can see the operation_name has the list_analyzers snake_case form but
we are using the ListAnalyzers form.
Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
"""
if operation_name == "GetJobs":
return {
"Jobs": [
{
"Name": "job",
"SecurityConfiguration": "security_config",
"DefaultArguments": {
"--encryption-type": "sse-s3",
"--enable-job-insights": "false",
},
}
]
}
elif operation_name == "GetConnections":
return {
"ConnectionList": [
{
"Name": "connection",
"ConnectionType": "JDBC",
"ConnectionProperties": {
"CONNECTOR_TYPE": "Jdbc",
"JDBC_CONNECTION_URL": '[["default=test"],":"]',
"CONNECTOR_URL": "s3://bck-dev",
"CONNECTOR_CLASS_NAME": "test",
"JDBC_ENFORCE_SSL": "true",
},
}
]
}
elif operation_name == "SearchTables":
return {
"TableList": [
{"Name": "table", "DatabaseName": "database", "CatalogId": "catalog"}
]
}
elif operation_name == "GetDevEndpoints":
return {
"DevEndpoints": [
{
"EndpointName": "endpoint",
"SecurityConfiguration": "security_config",
}
]
}
elif operation_name == "GetDataCatalogEncryptionSettings":
return {
"DataCatalogEncryptionSettings": {
"EncryptionAtRest": {
"CatalogEncryptionMode": "SSE-KMS",
"SseAwsKmsKeyId": "kms_key",
},
"ConnectionPasswordEncryption": {
"ReturnConnectionPasswordEncrypted": True,
"AwsKmsKeyId": "password_key",
},
}
}
elif operation_name == "GetSecurityConfigurations":
return {
"SecurityConfigurations": [
{
"Name": "test",
"EncryptionConfiguration": {
"S3Encryption": [
{
"S3EncryptionMode": "DISABLED",
},
],
"CloudWatchEncryption": {
"CloudWatchEncryptionMode": "DISABLED",
},
"JobBookmarksEncryption": {
"JobBookmarksEncryptionMode": "DISABLED",
},
},
},
],
}
return make_api_call(self, operation_name, kwarg)
# Mock generate_regional_clients()
def mock_generate_regional_clients(service, audit_info):
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
regional_client.region = AWS_REGION
return {AWS_REGION: regional_client}
# Patch every AWS call using Boto3 and generate_regional_clients to have 1 client
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
@patch(
"providers.aws.services.glue.glue_service.generate_regional_clients",
new=mock_generate_regional_clients,
)
class Test_Glue_Service:
# Mocked Audit Info
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
original_session=None,
audit_session=session.Session(
profile_name=None,
botocore_session=None,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,
profile=None,
profile_region=None,
credentials=None,
assumed_role_info=None,
audited_regions=None,
organizations_metadata=None,
)
return audit_info
# Test Glue Service
@mock_glue
def test_service(self):
# Glue client for this test class
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert glue.service == "glue"
# Test Glue Client
@mock_glue
def test_client(self):
# Glue client for this test class
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
for regional_client in glue.regional_clients.values():
assert regional_client.__class__.__name__ == "Glue"
# Test Glue Session
@mock_glue
def test__get_session__(self):
# Glue client for this test class
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert glue.session.__class__.__name__ == "Session"
# Test Glue Session
@mock_glue
def test_audited_account(self):
# Glue client for this test class
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert glue.audited_account == AWS_ACCOUNT_NUMBER
# Test Glue Search Tables
@mock_glue
def test__search_tables__(self):
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert len(glue.tables) == 1
assert glue.tables[0].name == "table"
assert glue.tables[0].database == "database"
assert glue.tables[0].catalog == "catalog"
assert glue.tables[0].region == AWS_REGION
# Test Glue Get Connections
@mock_glue
def test__get_connections__(self):
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert len(glue.connections) == 1
assert glue.connections[0].name == "connection"
assert glue.connections[0].type == "JDBC"
assert glue.connections[0].properties == {
"CONNECTOR_TYPE": "Jdbc",
"JDBC_CONNECTION_URL": '[["default=test"],":"]',
"CONNECTOR_URL": "s3://bck-dev",
"CONNECTOR_CLASS_NAME": "test",
"JDBC_ENFORCE_SSL": "true",
}
assert glue.connections[0].region == AWS_REGION
# Test Glue Get Catalog Encryption
@mock_glue
def test__get_data_catalog_encryption_settings__(self):
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert len(glue.catalog_encryption_settings) == 1
assert glue.catalog_encryption_settings[0].mode == "SSE-KMS"
assert glue.catalog_encryption_settings[0].kms_id == "kms_key"
assert glue.catalog_encryption_settings[0].password_encryption
assert glue.catalog_encryption_settings[0].password_kms_id == "password_key"
assert glue.catalog_encryption_settings[0].region == AWS_REGION
# Test Glue Get Dev Endpoints
@mock_glue
def test__get_dev_endpoints__(self):
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert len(glue.dev_endpoints) == 1
assert glue.dev_endpoints[0].name == "endpoint"
assert glue.dev_endpoints[0].security == "security_config"
assert glue.dev_endpoints[0].region == AWS_REGION
# Test Glue Get Security Configs
@mock_glue
def test__get_security_configurations__(self):
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert len(glue.security_configs) == 1
assert glue.security_configs[0].name == "test"
assert glue.security_configs[0].s3_encryption == "DISABLED"
assert glue.security_configs[0].cw_encryption == "DISABLED"
assert glue.security_configs[0].jb_encryption == "DISABLED"
assert glue.security_configs[0].region == AWS_REGION
# Test Glue Get Security Configs
@mock_glue
def test__get_jobs__(self):
audit_info = self.set_mocked_audit_info()
glue = Glue(audit_info)
assert len(glue.jobs) == 1
assert glue.jobs[0].name == "job"
assert glue.jobs[0].security == "security_config"
assert glue.jobs[0].arguments == {
"--encryption-type": "sse-s3",
"--enable-job-insights": "false",
}
assert glue.jobs[0].region == AWS_REGION