From 2756f16c87be6c08af9358bfbf9c8d3f0139c073 Mon Sep 17 00:00:00 2001 From: Stephen Jones Date: Thu, 22 Oct 2020 02:15:15 +1100 Subject: [PATCH 01/13] Adding fix to generate test summary so reports display graphs correctly --- include/junit_integration | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/junit_integration b/include/junit_integration index 090904db..e9ec77c3 100644 --- a/include/junit_integration +++ b/include/junit_integration @@ -61,6 +61,20 @@ prepare_junit_check_output() { finalise_junit_check_output() { echo '' >> "$JUNIT_OUTPUT_FILE" + TEST_COUNT="0" + TEST_SUCCESS_COUNT="0" + TEST_FAILURE_COUNT="0" + TEST_SKIPPED_COUNT="0" + TEST_ERROR_COUNT="0" + TEST_COUNT=$(grep -c "testcase name=" "$JUNIT_OUTPUT_FILE") + TEST_SUCCESS_COUNT=$(grep -A1 "testcase name=" "$JUNIT_OUTPUT_FILE" | grep -c "") + TEST_FAILURE_COUNT=$(grep -A1 "testcase name=" "$JUNIT_OUTPUT_FILE" | grep -c " "$JUNIT_OUTPUT_FILE.$$" && mv "$JUNIT_OUTPUT_FILE.$$" "$JUNIT_OUTPUT_FILE" } output_junit_success() { From 7585ad7d57b7f90861a5dfa8ff5fba8987e1126a Mon Sep 17 00:00:00 2001 From: Greg Soltis Date: Fri, 23 Oct 2020 10:17:01 -0700 Subject: [PATCH 02/13] Fix check for public rds instances --- checks/check_extra78 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks/check_extra78 b/checks/check_extra78 index 3c960994..b1d9c2ea 100644 --- a/checks/check_extra78 +++ b/checks/check_extra78 @@ -24,7 +24,7 @@ extra78(){ # "Ensure there are no Public Accessible RDS instances (Not Scored) (Not part of CIS benchmark)" textInfo "Looking for RDS instances in all regions... " for regx in $REGIONS; do - LIST_OF_RDS_PUBLIC_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[?PubliclyAccessible==`true` && DBInstanceStatus=="available"].[DBInstanceIdentifier,Endpoint.Address]' --output text) + LIST_OF_RDS_PUBLIC_INSTANCES=$($AWSCLI rds describe-db-instances $PROFILE_OPT --region $regx --query 'DBInstances[?PubliclyAccessible==`true` && DBInstanceStatus==`"available"`].[DBInstanceIdentifier,Endpoint.Address]' --output text) if [[ $LIST_OF_RDS_PUBLIC_INSTANCES ]];then while read -r rds_instance;do RDS_NAME=$(echo $rds_instance | awk '{ print $1; }') From 87f91cf4678b3378d9a9e70946b89ee916ab72f7 Mon Sep 17 00:00:00 2001 From: Stephen Jones Date: Fri, 30 Oct 2020 22:51:11 +1100 Subject: [PATCH 03/13] Removing gnarly code and add refined counters for summary metrics in output --- include/junit_integration | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/include/junit_integration b/include/junit_integration index e9ec77c3..a4854c6b 100644 --- a/include/junit_integration +++ b/include/junit_integration @@ -14,6 +14,11 @@ # Generates JUnit XML reports which can be read by Jenkins or other CI tools JUNIT_OUTPUT_DIRECTORY="junit-reports" +JUNIT_TESTS_COUNT="0" +JUNIT_SUCCESS_COUNT="0" +JUNIT_FAILURES_COUNT="0" +JUNIT_SKIPPED_COUNT="0" +JUNIT_ERRORS_COUNT="0" is_junit_output_enabled() { if [[ " ${MODES[@]} " =~ " junit-xml " ]]; then @@ -44,7 +49,7 @@ prepare_junit_check_output() { JUNIT_OUTPUT_FILE="$JUNIT_OUTPUT_DIRECTORY/TEST-$1.xml" printf '%s\n' \ "" \ - "" \ + "" \ " " \ " " \ " " \ @@ -60,24 +65,21 @@ prepare_junit_check_output() { } finalise_junit_check_output() { + # Calculate Total and populate summary info + JUNIT_TESTS_COUNT=$((JUNIT_SUCCESS_COUNT+$JUNIT_FAILURES_COUNT+$JUNIT_SKIPPED_COUNT+$JUNIT_ERRORS_COUNT)) + sed "s/_TESTS_COUNT_/${JUNIT_TESTS_COUNT}/g;s/_FAILURES_COUNT_/${JUNIT_FAILURES_COUNT}/g;s/_SKIPPED_COUNT_/${JUNIT_SKIPPED_COUNT}/g;s/_ERRORS_COUNT_/${JUNIT_ERRORS_COUNT}/g" "$JUNIT_OUTPUT_FILE" > "$JUNIT_OUTPUT_FILE.$$" + mv "$JUNIT_OUTPUT_FILE.$$" "$JUNIT_OUTPUT_FILE" echo '' >> "$JUNIT_OUTPUT_FILE" - TEST_COUNT="0" - TEST_SUCCESS_COUNT="0" - TEST_FAILURE_COUNT="0" - TEST_SKIPPED_COUNT="0" - TEST_ERROR_COUNT="0" - TEST_COUNT=$(grep -c "testcase name=" "$JUNIT_OUTPUT_FILE") - TEST_SUCCESS_COUNT=$(grep -A1 "testcase name=" "$JUNIT_OUTPUT_FILE" | grep -c "") - TEST_FAILURE_COUNT=$(grep -A1 "testcase name=" "$JUNIT_OUTPUT_FILE" | grep -c " "$JUNIT_OUTPUT_FILE.$$" && mv "$JUNIT_OUTPUT_FILE.$$" "$JUNIT_OUTPUT_FILE" + # Reset global counters as test output closed + JUNIT_TESTS_COUNT="0" + JUNIT_SUCCESS_COUNT="0" + JUNIT_FAILURES_COUNT="0" + JUNIT_SKIPPED_COUNT="0" + JUNIT_ERRORS_COUNT="0" } output_junit_success() { + JUNIT_SUCCESS_COUNT=$(($JUNIT_SUCCESS_COUNT+1)) output_junit_test_case "$1" "$(xml_escape "$1")" } @@ -87,10 +89,12 @@ output_junit_info() { } output_junit_failure() { + JUNIT_FAILURES_COUNT=$(($JUNIT_FAILURES_COUNT+1)) output_junit_test_case "$1" "" } output_junit_skipped() { + JUNIT_SKIPPED_COUNT=$(($UNIT_SKIPPED_COUNT+1)) output_junit_test_case "$1" "" } From e7f837eb7b9e6da3dc3cbec19403ee40aad145c4 Mon Sep 17 00:00:00 2001 From: Stephen Jones Date: Tue, 3 Nov 2020 22:45:27 +1100 Subject: [PATCH 04/13] Correct typo and simplify count --- include/junit_integration | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/junit_integration b/include/junit_integration index a4854c6b..dc1bdbc6 100644 --- a/include/junit_integration +++ b/include/junit_integration @@ -79,7 +79,7 @@ finalise_junit_check_output() { } output_junit_success() { - JUNIT_SUCCESS_COUNT=$(($JUNIT_SUCCESS_COUNT+1)) + ((JUNIT_SUCCESS_COUNT++)) output_junit_test_case "$1" "$(xml_escape "$1")" } @@ -89,12 +89,12 @@ output_junit_info() { } output_junit_failure() { - JUNIT_FAILURES_COUNT=$(($JUNIT_FAILURES_COUNT+1)) + ((JUNIT_FAILURES_COUNT++)) output_junit_test_case "$1" "" } output_junit_skipped() { - JUNIT_SKIPPED_COUNT=$(($UNIT_SKIPPED_COUNT+1)) + ((JUNIT_SKIPPED_COUNT++)) output_junit_test_case "$1" "" } From 954848c6e89671418339df440b8665d43e2b20b4 Mon Sep 17 00:00:00 2001 From: Ramon Diez Date: Wed, 4 Nov 2020 10:44:43 +0100 Subject: [PATCH 05/13] Glue checks part 1 --- checks/check_extra7115 | 38 ++++++++++++++++++++++++++++++++++ checks/check_extra7116 | 30 +++++++++++++++++++++++++++ checks/check_extra7117 | 30 +++++++++++++++++++++++++++ checks/check_extra7118 | 46 ++++++++++++++++++++++++++++++++++++++++++ checks/check_extra7120 | 43 +++++++++++++++++++++++++++++++++++++++ checks/check_extra7122 | 43 +++++++++++++++++++++++++++++++++++++++ groups/group23_glue | 19 +++++++++++++++++ 7 files changed, 249 insertions(+) create mode 100644 checks/check_extra7115 create mode 100644 checks/check_extra7116 create mode 100644 checks/check_extra7117 create mode 100644 checks/check_extra7118 create mode 100644 checks/check_extra7120 create mode 100644 checks/check_extra7122 create mode 100644 groups/group23_glue diff --git a/checks/check_extra7115 b/checks/check_extra7115 new file mode 100644 index 00000000..52f0f64b --- /dev/null +++ b/checks/check_extra7115 @@ -0,0 +1,38 @@ +#!/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 must have SSL connection enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7115="NOT_SCORED" +CHECK_TYPE_extra7115="EXTRA" +CHECK_SEVERITY_extra7115="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7115="AwsGlue" +CHECK_ALTERNATE_check7115="extra7115" + +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}') + if [[ ! -z "$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: Connection $CONNECTION_NAME has SSL connection disabled" "$regx" + else + textInfo "$regx: Connection $CONNECTION_NAME has SSL connection enabled" "$regx" + fi + done + else + textInfo "$regx: There are no connections" "$regx" + fi + done +} diff --git a/checks/check_extra7116 b/checks/check_extra7116 new file mode 100644 index 00000000..a789a8c2 --- /dev/null +++ b/checks/check_extra7116 @@ -0,0 +1,30 @@ +#!/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 Data catalog settings must have metadata encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7116="NOT_SCORED" +CHECK_TYPE_extra7116="EXTRA" +CHECK_SEVERITY_extra7116="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7116="AwsGlue" +CHECK_ALTERNATE_check7116="extra7116" + +extra7116(){ + for regx in $REGIONS; do + 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 Catalog is not encrypted" "$regx" + else + textInfo "$regx:Glue catalog is encrypted with $METADATA_ENCRYPTED" "$regx" + fi + done +} diff --git a/checks/check_extra7117 b/checks/check_extra7117 new file mode 100644 index 00000000..ac195606 --- /dev/null +++ b/checks/check_extra7117 @@ -0,0 +1,30 @@ +#!/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 Data catalog settings must have Encrypt connection password enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7117="NOT_SCORED" +CHECK_TYPE_extra7117="EXTRA" +CHECK_SEVERITY_extra7117="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7117="AwsGlue" +CHECK_ALTERNATE_check7117="extra7117" + +extra7117(){ + for regx in $REGIONS; do + 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 Catalog connection password is not encrypted" "$regx" + else + textInfo "$regx:Glue catalog connection password is encrypted" "$regx" + fi + done +} diff --git a/checks/check_extra7118 b/checks/check_extra7118 new file mode 100644 index 00000000..3cc70617 --- /dev/null +++ b/checks/check_extra7118 @@ -0,0 +1,46 @@ +#!/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.117" +CHECK_TITLE_extra7118="[extra7118] Check if Security configurations used by ETL Jobs have S3 encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7118="NOT_SCORED" +CHECK_TYPE_extra7118="EXTRA" +CHECK_SEVERITY_extra7118="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7118="AwsGlue" +CHECK_ALTERNATE_check7118="extra7118" + +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"}') + if [[ ! -z "$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 + textFail "$regx: Job $JOB_NAME does not have S3 encryption enabled" "$regx" + else + textInfo "$regx: Job $JOB_NAME does have $S3_ENCRYPTION S3 encryption enabled" "$regx" + fi + elif [[ ! -z "$JOB_ENCRYPTION" ]]; then + textInfo "$regx: Job $JOB_NAME does have $JOB_ENCRYPTION S3 encryption enabled" "$regx" + else + textFail "$regx: Job $JOB_NAME does not have S3 encryption enabled" "$regx" + fi + done + else + textInfo "$regx: There are no jobs" "$regx" + fi + done +} \ No newline at end of file diff --git a/checks/check_extra7120 b/checks/check_extra7120 new file mode 100644 index 00000000..c2782e5f --- /dev/null +++ b/checks/check_extra7120 @@ -0,0 +1,43 @@ +#!/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.117" +CHECK_TITLE_extra7120="[extra7120] Check if Security configurations used by ETL Jobs have CloudWatch logs encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7120="NOT_SCORED" +CHECK_TYPE_extra7120="EXTRA" +CHECK_SEVERITY_extra7120="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7120="AwsGlue" +CHECK_ALTERNATE_check7120="extra7120" + +extra7120(){ + for regx in $REGIONS; do + JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}') + if [[ ! -z "$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: Job $JOB_NAME does not have CloudWatch logs encryption enabled" "$regx" + else + textInfo "$regx: Job $JOB_NAME does have $CLOUDWATCH_ENCRYPTION CloudWatch logs encryption enabled" "$regx" + fi + else + textFail "$regx: Job $JOB_NAME does not have CloudWatch logs encryption enabled" "$regx" + fi + done + else + textInfo "$regx: There are no jobs" "$regx" + fi + done +} \ No newline at end of file diff --git a/checks/check_extra7122 b/checks/check_extra7122 new file mode 100644 index 00000000..0ef7bc9d --- /dev/null +++ b/checks/check_extra7122 @@ -0,0 +1,43 @@ +#!/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.117" +CHECK_TITLE_extra7122="[extra7122] Check if Security configurations used by ETL Jobs have Job bookmark encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_SCORED_extra7122="NOT_SCORED" +CHECK_TYPE_extra7122="EXTRA" +CHECK_SEVERITY_extra7122="Medium" +CHECK_ASFF_RESOURCE_TYPE_extra7122="AwsGlue" +CHECK_ALTERNATE_check7122="extra7122" + +extra7122(){ + for regx in $REGIONS; do + JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}') + 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: Job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" + else + textInfo "$regx: Job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION Job bookmark encryption enabled" "$regx" + fi + else + textFail "$regx: Job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" + fi + done + else + textInfo "$regx: There are no jobs" "$regx" + fi + done +} \ No newline at end of file diff --git a/groups/group23_glue b/groups/group23_glue new file mode 100644 index 00000000..61bb8718 --- /dev/null +++ b/groups/group23_glue @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2222) 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. + +GROUP_ID[23]='glue' +GROUP_NUMBER[23]='23.0' +GROUP_TITLE[23]='Amazon Glue related security checks - [glue] ********' +GROUP_RUN_BY_DEFAULT[23]='N' # run it when execute_all is called +GROUP_CHECKS[23]='extra7115,extra7116,extra7117,extra7118,extra7120,extra7122' + From 2304d14f28900841f2bf45e61ef38561ec61335d Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Thu, 5 Nov 2020 00:35:05 +0100 Subject: [PATCH 06/13] Added CodeBuild template - original from @stevecjones --- .../codebuild-auditor-account-cfn.yaml | 216 ++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 util/codebuild/codebuild-auditor-account-cfn.yaml diff --git a/util/codebuild/codebuild-auditor-account-cfn.yaml b/util/codebuild/codebuild-auditor-account-cfn.yaml new file mode 100644 index 00000000..213a2703 --- /dev/null +++ b/util/codebuild/codebuild-auditor-account-cfn.yaml @@ -0,0 +1,216 @@ +--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Creates a CodeBuild project to audit the AWS account with Prowler and stores the html report in a S3 bucket / Original author https://github.com/stevecjones +Parameters: + ServiceName: + Description: 'Specifies the service name used within component naming' + Type: String + Default: 'prowler' + + LogsRetentionInDays: + Description: 'Specifies the number of days you want to retain CodeBuild run log events in the specified log group. Junit reports are kept for 30 days' + Type: Number + Default: 3 + AllowedValues: [1, 3, 5, 7, 14, 30, 60] + + ProwlerOptions: + Description: 'Options to pass to Prowler command, make sure at least -M junit-xml is used. -r for the region to send API queries, -f to filter only that region, -M output formats, -c for comma separated checks, for all checks do not use -c, for more options see -h' + Type: String + Default: -r eu-west-1 -f eu-west-1 -M text,junit-xml,html -c check11,check12,check13,check14 + +Resources: + ArtifactBucket: + Type: AWS::S3::Bucket + Properties: + Tags: + - Key: Name + Value: !Join ['-', ['AP2', 'INF', !Ref 'ServiceName', !Ref 'AWS::AccountId', 'S3', 'Prowler']] + BucketName: !Sub '${ServiceName}-${AWS::Region}-prowler-${AWS::AccountId}' + AccessControl: LogDeliveryWrite + VersioningConfiguration: + Status: Enabled + # LoggingConfiguration: + # DestinationBucketName: !ImportValue 'ProviderLogBucket' + # LogFilePrefix: !Sub '${ServiceName}-${AWS::Region}-prowler-${AWS::AccountId}/' + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: AES256 + PublicAccessBlockConfiguration: + BlockPublicAcls: true + BlockPublicPolicy: true + IgnorePublicAcls: true + RestrictPublicBuckets: true + + ArtifactBucketPolicy: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: !Ref 'ArtifactBucket' + PolicyDocument: + Id: Content + Version: '2012-10-17' + Statement: + - Action: '*' + Condition: + Bool: + aws:SecureTransport: 'false' + Effect: Deny + Principal: '*' + Resource: + - !Join ['', ['arn:aws:s3:::', !Ref 'ArtifactBucket', '/*']] + Sid: S3ForceSSL + - Action: 's3:PutObject' + Condition: + 'Null': + s3:x-amz-server-side-encryption: 'true' + Effect: Deny + Principal: '*' + Resource: + - !Join ['', ['arn:aws:s3:::', !Ref 'ArtifactBucket', '/*']] + Sid: DenyUnEncryptedObjectUploads + + # Codebuild Project + CodeBuildServiceRole: + Type: AWS::IAM::Role + Metadata: + cfn_nag: + rules_to_suppress: + - id: W28 + reason: "Explicit name is required for this resource to avoid circular dependencies." + Properties: + RoleName: prowler-codebuild-role + Path: '/service-role/' + ManagedPolicyArns: + - 'arn:aws:iam::aws:policy/job-function/SupportUser' + - 'arn:aws:iam::aws:policy/job-function/ViewOnlyAccess' + - 'arn:aws:iam::aws:policy/SecurityAudit' + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - + Action: 'sts:AssumeRole' + Effect: Allow + Principal: + Service: + - codebuild.amazonaws.com + Policies: + - PolicyName: LogGroup + PolicyDocument: + Version: '2012-10-17' + Statement: + - Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Effect: Allow + Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*' + - PolicyName: S3 + PolicyDocument: + Version: '2012-10-17' + Statement: + - Action: + - s3:PutObject + - s3:GetObject + - s3:GetObjectVersion + - s3:GetBucketAcl + - s3:GetBucketLocation + Effect: Allow + Resource: !Sub 'arn:aws:s3:::${ArtifactBucket}/*' + - PolicyName: CodeBuild + PolicyDocument: + Version: '2012-10-17' + Statement: + - Action: + - codebuild:CreateReportGroup + - codebuild:CreateReport + - codebuild:UpdateReport + - codebuild:BatchPutTestCases + - codebuild:BatchPutCodeCoverages + Effect: Allow + Resource: !Sub 'arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/*' + - PolicyName: AssumeRole + PolicyDocument: + Version: '2012-10-17' + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:role/service-role/prowler-codebuild-role' + + ProwlerCodeBuild: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + Source: + Type: NO_SOURCE + # Prowler command below runs a set of checks, configure it base on your needs, no options will run all regions all checks. + # option -M junit-xml is requirede in order to get the report in CodeBuild. + BuildSpec: | + version: 0.2 + phases: + install: + runtime-versions: + python: 3.8 + commands: + - echo "Installing Prowler and dependencies..." + - pip3 install detect-secrets + - yum -y install jq + - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + - unzip awscliv2.zip + - ./aws/install + - git clone https://github.com/toniblyx/prowler + build: + commands: + - echo "Running Prowler..." + - cd prowler + - ./prowler $PROWLER_OPTIONS + post_build: + commands: + - echo "Uploading reports to S3..." + - aws s3 cp --sse AES256 output/*.html s3://$BUCKET_REPORT/ + - echo "Done!" + reports: + prowler: + files: + - '**/*' + base-directory: 'prowler/junit-reports' + file-format: JunitXml + Environment: + # UILD_GENERAL1_SMALL: Use up to 3 GB memory and 2 vCPUs for builds. + # BUILD_GENERAL1_MEDIUM: Use up to 7 GB memory and 4 vCPUs for builds. + # BUILD_GENERAL1_LARGE: Use up to 15 GB memory and 8 vCPUs for builds. + ComputeType: "BUILD_GENERAL1_SMALL" + Image: "aws/codebuild/amazonlinux2-x86_64-standard:3.0" + Type: "LINUX_CONTAINER" + EnvironmentVariables: + - Name: BUCKET_REPORT + Value: !Ref 'ArtifactBucket' + Type: PLAINTEXT + - Name: PROWLER_OPTIONS + Value: !Ref 'ProwlerOptions' + Type: PLAINTEXT + Description: Run Prowler assessment + ServiceRole: !GetAtt CodeBuildServiceRole.Arn + TimeoutInMinutes: 300 + + ProwlerCodeBuildReportGroup: + Type: AWS::CodeBuild::ReportGroup + Properties: + Name: prowler + Type: TEST + ExportConfig: + ExportConfigType: NO_EXPORT + + ProwlerLogGroup: + Type: 'AWS::Logs::LogGroup' + Properties: + LogGroupName: !Sub '/aws/codebuild/${ProwlerCodeBuild}' + RetentionInDays: !Ref LogsRetentionInDays + +Outputs: + ArtifactBucketName: + Description: Artifact Bucket Name + Value: !Ref 'ArtifactBucket' + Export: + Name: !Sub 'ArtifactBucketName-${ServiceName}' \ No newline at end of file From 7dbed6314371f9e131edd51c4c706db4ce24458e Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Thu, 5 Nov 2020 21:49:05 +0100 Subject: [PATCH 07/13] Added CodeBuild deployment section --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3f4acbb0..9ee849d6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ - [Screenshots](#screenshots) - [Advanced Usage](#advanced-usage) - [Security Hub integration](#security-hub-integration) -- [Fix](#fix) +- [CodeBuild deployment](#codebuild-deployment) +- [Whitelist/allowlist or remove FAIL from resources](whitelist-allowlist-or-remove-fail-from-resources) +- [Fix](#how-to-fix-every-fail) - [Troubleshooting](#troubleshooting) - [Extras](#extras) - [Forensics Ready Checks](#forensics-ready-checks) @@ -381,7 +383,11 @@ To use Prowler and Security Hub integration in China regions there is an additio ./prowler -r cn-north-1 -f cn-north-1 -q -S -M csv,json-asff ``` -## Whitelist or remove FAIL from resources +## CodeBuild deployment + +CodeBuild can help you running Prowler and there is a Cloud Formation template that helps you doing that [here](https://github.com/toniblyx/prowler/blob/master/util/codebuild/codebuild-auditor-account-cfn.yaml). + +## Whitelist or allowlist or remove a fail from resources Sometimes you may find resources that are intentionally configured in a certain way that may be a bad practice but it is all right with it, for example an S3 bucket open to the internet hosting a web site, or a security group with an open port needed in your use case. Now you can use `-w whitelist_sample.txt` and add your resources as `checkID:resourcename` as in this command: From 0bfa263ad95787a4ba7e0fa098938eaf986c9830 Mon Sep 17 00:00:00 2001 From: Ramon Diez Date: Thu, 12 Nov 2020 12:30:22 +0100 Subject: [PATCH 08/13] Fixing some descriptions --- checks/check_extra7115 | 8 ++++---- checks/check_extra7116 | 4 ++-- checks/check_extra7117 | 4 ++-- checks/check_extra7118 | 12 ++++++------ checks/check_extra7120 | 10 +++++----- checks/check_extra7122 | 10 +++++----- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/checks/check_extra7115 b/checks/check_extra7115 index 52f0f64b..a8b5b166 100644 --- a/checks/check_extra7115 +++ b/checks/check_extra7115 @@ -11,7 +11,7 @@ # 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 must have SSL connection enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7115="[extra7115] Check if Glue database connection must have SSL connection enabled. (Not Scored) (Not part of CIS benchmark)" CHECK_SCORED_extra7115="NOT_SCORED" CHECK_TYPE_extra7115="EXTRA" CHECK_SEVERITY_extra7115="Medium" @@ -26,13 +26,13 @@ extra7115(){ 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: Connection $CONNECTION_NAME has SSL connection disabled" "$regx" + textFail "$regx: Glue connection $CONNECTION_NAME has SSL connection disabled" "$regx" else - textInfo "$regx: Connection $CONNECTION_NAME has SSL connection enabled" "$regx" + textInfo "$regx: Glue connection $CONNECTION_NAME has SSL connection enabled" "$regx" fi done else - textInfo "$regx: There are no connections" "$regx" + textInfo "$regx: There are no Glue connections" "$regx" fi done } diff --git a/checks/check_extra7116 b/checks/check_extra7116 index a789a8c2..d862559c 100644 --- a/checks/check_extra7116 +++ b/checks/check_extra7116 @@ -11,7 +11,7 @@ # 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 Data catalog settings must have metadata encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7116="[extra7116] Check if Glue data-catalog settings must have metadata encryption enabled. (Not Scored) (Not part of CIS benchmark)" CHECK_SCORED_extra7116="NOT_SCORED" CHECK_TYPE_extra7116="EXTRA" CHECK_SEVERITY_extra7116="Medium" @@ -24,7 +24,7 @@ extra7116(){ if [[ "$METADATA_ENCRYPTED" == "DISABLED" ]]; then textFail "$regx: Glue Catalog is not encrypted" "$regx" else - textInfo "$regx:Glue catalog is encrypted with $METADATA_ENCRYPTED" "$regx" + textInfo "$regx: Glue catalog is encrypted with $METADATA_ENCRYPTED" "$regx" fi done } diff --git a/checks/check_extra7117 b/checks/check_extra7117 index ac195606..6a019c70 100644 --- a/checks/check_extra7117 +++ b/checks/check_extra7117 @@ -11,7 +11,7 @@ # 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 Data catalog settings must have Encrypt connection password enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7117="[extra7117] Check if Glue data-catalog settings must have Encrypt connection password enabled. (Not Scored) (Not part of CIS benchmark)" CHECK_SCORED_extra7117="NOT_SCORED" CHECK_TYPE_extra7117="EXTRA" CHECK_SEVERITY_extra7117="Medium" @@ -24,7 +24,7 @@ extra7117(){ if [[ "$METADATA_ENCRYPTED" == "False" ]]; then textFail "$regx: Glue Catalog connection password is not encrypted" "$regx" else - textInfo "$regx:Glue catalog connection password is encrypted" "$regx" + textInfo "$regx: Glue catalog connection password is encrypted" "$regx" fi done } diff --git a/checks/check_extra7118 b/checks/check_extra7118 index 3cc70617..516b3086 100644 --- a/checks/check_extra7118 +++ b/checks/check_extra7118 @@ -11,7 +11,7 @@ # 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.117" -CHECK_TITLE_extra7118="[extra7118] Check if Security configurations used by ETL Jobs have S3 encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7118="[extra7118] Check if Glue Security configurations used by ETL Jobs have S3 encryption enabled. (Not Scored) (Not part of CIS benchmark)" CHECK_SCORED_extra7118="NOT_SCORED" CHECK_TYPE_extra7118="EXTRA" CHECK_SEVERITY_extra7118="Medium" @@ -29,18 +29,18 @@ extra7118(){ 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 - textFail "$regx: Job $JOB_NAME does not have S3 encryption enabled" "$regx" + textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" else - textInfo "$regx: Job $JOB_NAME does have $S3_ENCRYPTION S3 encryption enabled" "$regx" + textInfo "$regx: Glue job $JOB_NAME does have $S3_ENCRYPTION S3 encryption enabled" "$regx" fi elif [[ ! -z "$JOB_ENCRYPTION" ]]; then - textInfo "$regx: Job $JOB_NAME does have $JOB_ENCRYPTION S3 encryption enabled" "$regx" + textInfo "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION S3 encryption enabled" "$regx" else - textFail "$regx: Job $JOB_NAME does not have S3 encryption enabled" "$regx" + textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" fi done else - textInfo "$regx: There are no jobs" "$regx" + textInfo "$regx: There are no Glue jobs" "$regx" fi done } \ No newline at end of file diff --git a/checks/check_extra7120 b/checks/check_extra7120 index c2782e5f..751f74f2 100644 --- a/checks/check_extra7120 +++ b/checks/check_extra7120 @@ -11,7 +11,7 @@ # 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.117" -CHECK_TITLE_extra7120="[extra7120] Check if Security configurations used by ETL Jobs have CloudWatch logs encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7120="[extra7120] Check if Glue security configurations used by ETL Jobs have CloudWatch logs encryption enabled. (Not Scored) (Not part of CIS benchmark)" CHECK_SCORED_extra7120="NOT_SCORED" CHECK_TYPE_extra7120="EXTRA" CHECK_SEVERITY_extra7120="Medium" @@ -28,16 +28,16 @@ extra7120(){ 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: Job $JOB_NAME does not have CloudWatch logs encryption enabled" "$regx" + textFail "$regx: Glue job $JOB_NAME does not have CloudWatch logs encryption enabled" "$regx" else - textInfo "$regx: Job $JOB_NAME does have $CLOUDWATCH_ENCRYPTION CloudWatch logs encryption enabled" "$regx" + textInfo "$regx: Glue job $JOB_NAME does have $CLOUDWATCH_ENCRYPTION CloudWatch logs encryption enabled" "$regx" fi else - textFail "$regx: Job $JOB_NAME does not have CloudWatch logs encryption enabled" "$regx" + textFail "$regx: Glue job $JOB_NAME does not have CloudWatch logs encryption enabled" "$regx" fi done else - textInfo "$regx: There are no jobs" "$regx" + textInfo "$regx: There are no Glue jobs" "$regx" fi done } \ No newline at end of file diff --git a/checks/check_extra7122 b/checks/check_extra7122 index 0ef7bc9d..438be869 100644 --- a/checks/check_extra7122 +++ b/checks/check_extra7122 @@ -11,7 +11,7 @@ # 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.117" -CHECK_TITLE_extra7122="[extra7122] Check if Security configurations used by ETL Jobs have Job bookmark encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7122="[extra7122] Check if Glue security configurations used by ETL Jobs have Job bookmark encryption enabled. (Not Scored) (Not part of CIS benchmark)" CHECK_SCORED_extra7122="NOT_SCORED" CHECK_TYPE_extra7122="EXTRA" CHECK_SEVERITY_extra7122="Medium" @@ -28,16 +28,16 @@ extra7122(){ 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: Job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" + textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" else - textInfo "$regx: Job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION Job bookmark encryption enabled" "$regx" + textInfo "$regx: Glue job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION Job bookmark encryption enabled" "$regx" fi else - textFail "$regx: Job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" + textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" fi done else - textInfo "$regx: There are no jobs" "$regx" + textInfo "$regx: There are no Glue jobs" "$regx" fi done } \ No newline at end of file From f6d17ba6e0e518609581feec32d811c6d2c5fc4d Mon Sep 17 00:00:00 2001 From: Joaquin Rinaudo Date: Thu, 12 Nov 2020 21:01:52 +0100 Subject: [PATCH 09/13] fix(securityhub): consistency + prefix bug + PASSED fix(securityhub): consistency + prefix bug + PASSED --- include/os_detector | 28 ---------------------------- include/securityhub_integration | 13 +++++++------ prowler | 2 ++ 3 files changed, 9 insertions(+), 34 deletions(-) diff --git a/include/os_detector b/include/os_detector index 91fd9ce4..af962d4c 100644 --- a/include/os_detector +++ b/include/os_detector @@ -104,26 +104,10 @@ gnu_get_iso8601_timestamp() { "$DATE_CMD" -u +"%Y-%m-%dT%H:%M:%SZ" } -gsu_get_iso8601_one_minute_ago() { - "$DATE_CMD" -d "1 minute ago" -u +"%Y-%m-%dT%H:%M:%SZ" -} - -gsu_get_iso8601_hundred_days_ago() { - "$DATE_CMD" -d "100 days ago" -u +"%Y-%m-%dT%H:%M:%SZ" -} - bsd_get_iso8601_timestamp() { "$DATE_CMD" -u +"%Y-%m-%dT%H:%M:%SZ" } -bsd_get_iso8601_hundred_days_ago() { - "$DATE_CMD" -v-100d -u +"%Y-%m-%dT%H:%M:%SZ" -} - -bsd_get_iso8601_one_minute_ago() { - "$DATE_CMD" -v-1M -u +"%Y-%m-%dT%H:%M:%SZ" -} - gnu_test_tcp_connectivity() { HOST=$1 PORT=$2 @@ -167,12 +151,6 @@ if [ "$OSTYPE" == "linux-gnu" ] || [ "$OSTYPE" == "linux-musl" ]; then get_iso8601_timestamp() { gnu_get_iso8601_timestamp } - get_iso8601_one_minute_ago() { - gsu_get_iso8601_one_minute_ago - } - get_iso8601_hundred_days_ago() { - gsu_get_iso8601_hundred_days_ago - } test_tcp_connectivity() { gnu_test_tcp_connectivity "$1" "$2" "$3" } @@ -230,12 +208,6 @@ elif [[ "$OSTYPE" == "darwin"* ]]; then get_iso8601_timestamp() { bsd_get_iso8601_timestamp } - get_iso8601_one_minute_ago() { - bsd_get_iso8601_one_minute_ago - } - get_iso8601_hundred_days_ago() { - bsd_get_iso8601_hundred_days_ago - } fi if "$BASE64_CMD" --version >/dev/null 2>&1 ; then decode_report() { diff --git a/include/securityhub_integration b/include/securityhub_integration index 790ea415..cf03cb0a 100644 --- a/include/securityhub_integration +++ b/include/securityhub_integration @@ -14,7 +14,6 @@ # Checks that the correct mode (json-asff) has been specified if wanting to send check output to AWS Security Hub # and that Security Hub is enabled in the chosen region checkSecurityHubCompatibility(){ - OLD_TIMESTAMP=$(get_iso8601_one_minute_ago) local regx if [[ "${MODE}" != "json-asff" ]]; then @@ -48,16 +47,16 @@ resolveSecurityHubPreviousFails(){ local check="$1" NEW_TIMESTAMP=$(get_iso8601_timestamp) - PREVIOUS_DATE=$(get_iso8601_hundred_days_ago) + FILTER="{\"GeneratorId\":[{\"Value\": \"prowler-$check\",\"Comparison\":\"EQUALS\"}],\"RecordState\":[{\"Value\": \"ACTIVE\",\"Comparison\":\"EQUALS\"}]}" + + NEW_FINDING_IDS=$(echo -n "${SECURITYHUB_NEW_FINDINGS_IDS[@]}" | jq -cRs 'split(" ")') + SECURITY_HUB_PREVIOUS_FINDINGS=$($AWSCLI securityhub --region "$regx" $PROFILE_OPT get-findings --filters "${FILTER}" | jq -c --argjson ids "$NEW_FINDING_IDS" --arg updated_at $NEW_TIMESTAMP '[ .Findings[] | select( .Id| first(select($ids[] == .)) // false | not) | .RecordState = "ARCHIVED" | .UpdatedAt = $updated_at ]') - FILTER="{\"UpdatedAt\":[{\"Start\":\"$PREVIOUS_DATE\",\"End\":\"$OLD_TIMESTAMP\"}],\"GeneratorId\":[{\"Value\": \"prowler-$check\",\"Comparison\":\"PREFIX\"}],\"ComplianceStatus\":[{\"Value\": \"FAILED\",\"Comparison\":\"EQUALS\"}],\"RecordState\":[{\"Value\": \"ACTIVE\",\"Comparison\":\"EQUALS\"}]}" - SECURITY_HUB_PREVIOUS_FINDINGS=$($AWSCLI securityhub --region "$regx" $PROFILE_OPT get-findings --filters "${FILTER}" | jq -c --arg updated_at $NEW_TIMESTAMP '[ .Findings[] | .RecordState = "ARCHIVED" | .UpdatedAt = $updated_at ]') if [[ $SECURITY_HUB_PREVIOUS_FINDINGS != "[]" ]]; then FINDINGS_COUNT=$(echo $SECURITY_HUB_PREVIOUS_FINDINGS | jq '. | length') for i in `seq 0 100 $FINDINGS_COUNT`; do - # Import in batches of 100 - BATCH_FINDINGS=$(echo $SECURITY_HUB_PREVIOUS_FINDINGS | jq '.['"$i:$i+100"']') + BATCH_FINDINGS=$(echo $SECURITY_HUB_PREVIOUS_FINDINGS | jq -c '.['"$i:$i+100"']') BATCH_IMPORT_RESULT=$($AWSCLI securityhub --region "$regx" $PROFILE_OPT batch-import-findings --findings "${BATCH_FINDINGS}") if [[ -z "${BATCH_IMPORT_RESULT}" ]] || jq -e '.FailedCount >= 1' <<< "${BATCH_IMPORT_RESULT}" > /dev/null 2>&1; then echo -e "\n$RED ERROR!$NORMAL Failed to send check output to AWS Security Hub\n" @@ -73,6 +72,8 @@ sendToSecurityHub(){ local findings="$1" local region="$2" + local finding_id=$(echo ${findings} | jq -r .Id ) + SECURITYHUB_NEW_FINDINGS_IDS+=( "$finding_id" ) BATCH_IMPORT_RESULT=$($AWSCLI securityhub --region "$region" $PROFILE_OPT batch-import-findings --findings "${findings}") # Check for success if imported diff --git a/prowler b/prowler index b56c66ba..c88fab83 100755 --- a/prowler +++ b/prowler @@ -331,6 +331,8 @@ execute_check() { ASFF_RESOURCE_TYPE="${!asff_resource_type_var:-AwsAccount}" + SECURITYHUB_NEW_FINDINGS_IDS=() + # Generate the credential report, only if it is group1 related which checks we # run so that the checks can safely assume it's available # set the custom ignores list for this check From c9ca8d48b1900c63ef9767abdb138c40077b5a74 Mon Sep 17 00:00:00 2001 From: Grzegorz Nittner Date: Fri, 13 Nov 2020 14:56:22 +0000 Subject: [PATCH 10/13] #680 - fix for check_extra764 --- checks/check_extra764 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/checks/check_extra764 b/checks/check_extra764 index 435cf474..d04768d4 100644 --- a/checks/check_extra764 +++ b/checks/check_extra764 @@ -47,7 +47,8 @@ extra764(){ # checking if $TEMP_STP_POLICY_FILE is a valid json before converting it to json with jq policy_str=$(cat "$TEMP_STP_POLICY_FILE") if jq -e . >/dev/null 2>&1 <<< "$policy_str"; then - CHECK_BUCKET_STP_POLICY_PRESENT=$(cat $TEMP_STP_POLICY_FILE | jq --arg arn "arn:${AWS_PARTITION}:s3:::${bucket}" '.Statement[]|select((((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and .Action=="s3:*" and (.Resource|type == "array") and (.Resource|map({(.):0})[]|has($arn)) and (.Resource|map({(.):0})[]|has($arn+"/*")) and .Condition.Bool."aws:SecureTransport" == "false")') + CHECK_BUCKET_STP_POLICY_PRESENT=$(cat $TEMP_STP_POLICY_FILE | jq --arg arn "arn:${AWS_PARTITION}:s3:::${bucket}" \ + '.Statement[]|select((((.Principal|type == "object") and .Principal.AWS == "*") or ((.Principal|type == "string") and .Principal == "*")) and .Effect=="Deny" and (.Action=="s3:*" or .Action=="*") and (.Resource|type == "array") and (.Resource|map({(.):0})[]|has($arn)) and (.Resource|map({(.):0})[]|has($arn+"/*")) and .Condition.Bool."aws:SecureTransport" == "false")') if [[ $CHECK_BUCKET_STP_POLICY_PRESENT ]]; then textPass "Bucket $bucket has S3 bucket policy to deny requests over insecure transport" else From c934e788b78a8ec4a31e0cc6d23c061a11a17a9e Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Fri, 13 Nov 2020 18:22:09 +0100 Subject: [PATCH 11/13] Center logo in html report --- include/html_report | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/html_report b/include/html_report index ee606eff..b38a2eca 100644 --- a/include/html_report +++ b/include/html_report @@ -58,7 +58,7 @@ addHtmlHeader() {
  • Date: $TIMESTAMP
  • -
  • +
  • prowler-logo
  • From 8c9d843813d41e0cbe27864eb6136bf7b93c1d90 Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Fri, 13 Nov 2020 19:02:26 +0100 Subject: [PATCH 12/13] Glue review 1 --- checks/check_extra7115 | 2 +- checks/check_extra7116 | 6 +++--- checks/check_extra7117 | 2 +- checks/check_extra7118 | 2 +- checks/check_extra7120 | 2 +- checks/check_extra7122 | 2 +- groups/group23_glue | 19 ------------------- 7 files changed, 8 insertions(+), 27 deletions(-) delete mode 100644 groups/group23_glue diff --git a/checks/check_extra7115 b/checks/check_extra7115 index a8b5b166..ad597b07 100644 --- a/checks/check_extra7115 +++ b/checks/check_extra7115 @@ -11,7 +11,7 @@ # 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 must have SSL connection enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7115="[extra7115] Check if Glue database connection has SSL connection enabled." CHECK_SCORED_extra7115="NOT_SCORED" CHECK_TYPE_extra7115="EXTRA" CHECK_SEVERITY_extra7115="Medium" diff --git a/checks/check_extra7116 b/checks/check_extra7116 index d862559c..aa778774 100644 --- a/checks/check_extra7116 +++ b/checks/check_extra7116 @@ -11,7 +11,7 @@ # 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 must have metadata encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7116="[extra7116] Check if Glue data-catalog settings have metadata encryption enabled." CHECK_SCORED_extra7116="NOT_SCORED" CHECK_TYPE_extra7116="EXTRA" CHECK_SEVERITY_extra7116="Medium" @@ -22,9 +22,9 @@ extra7116(){ for regx in $REGIONS; do 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 Catalog is not encrypted" "$regx" + textFail "$regx: Glue data-catalog settings have metadata encryption disabled" "$regx" else - textInfo "$regx: Glue catalog is encrypted with $METADATA_ENCRYPTED" "$regx" + textInfo "$regx: Glue data-catalog settings have metadata encryption enabled" "$regx" fi done } diff --git a/checks/check_extra7117 b/checks/check_extra7117 index 6a019c70..cd8b66b5 100644 --- a/checks/check_extra7117 +++ b/checks/check_extra7117 @@ -11,7 +11,7 @@ # 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 must have Encrypt connection password enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7117="[extra7117] Check if Glue data-catalog settings have Encrypt connection password enabled." CHECK_SCORED_extra7117="NOT_SCORED" CHECK_TYPE_extra7117="EXTRA" CHECK_SEVERITY_extra7117="Medium" diff --git a/checks/check_extra7118 b/checks/check_extra7118 index 516b3086..abc02ac7 100644 --- a/checks/check_extra7118 +++ b/checks/check_extra7118 @@ -11,7 +11,7 @@ # 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.117" -CHECK_TITLE_extra7118="[extra7118] Check if Glue Security configurations used by ETL Jobs have S3 encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7118="[extra7118] Check if Glue security configurations used by ETL Jobs have S3 encryption enabled." CHECK_SCORED_extra7118="NOT_SCORED" CHECK_TYPE_extra7118="EXTRA" CHECK_SEVERITY_extra7118="Medium" diff --git a/checks/check_extra7120 b/checks/check_extra7120 index 751f74f2..32a6053b 100644 --- a/checks/check_extra7120 +++ b/checks/check_extra7120 @@ -11,7 +11,7 @@ # 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.117" -CHECK_TITLE_extra7120="[extra7120] Check if Glue security configurations used by ETL Jobs have CloudWatch logs encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7120="[extra7120] Check if Glue security configurations used by ETL Jobs have CloudWatch logs encryption enabled." CHECK_SCORED_extra7120="NOT_SCORED" CHECK_TYPE_extra7120="EXTRA" CHECK_SEVERITY_extra7120="Medium" diff --git a/checks/check_extra7122 b/checks/check_extra7122 index 438be869..3ea87a2d 100644 --- a/checks/check_extra7122 +++ b/checks/check_extra7122 @@ -11,7 +11,7 @@ # 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.117" -CHECK_TITLE_extra7122="[extra7122] Check if Glue security configurations used by ETL Jobs have Job bookmark encryption enabled. (Not Scored) (Not part of CIS benchmark)" +CHECK_TITLE_extra7122="[extra7122] Check if Glue security configurations used by ETL Jobs have Job bookmark encryption enabled." CHECK_SCORED_extra7122="NOT_SCORED" CHECK_TYPE_extra7122="EXTRA" CHECK_SEVERITY_extra7122="Medium" diff --git a/groups/group23_glue b/groups/group23_glue deleted file mode 100644 index 61bb8718..00000000 --- a/groups/group23_glue +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -# Prowler - the handy cloud security tool (copyright 2222) 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. - -GROUP_ID[23]='glue' -GROUP_NUMBER[23]='23.0' -GROUP_TITLE[23]='Amazon Glue related security checks - [glue] ********' -GROUP_RUN_BY_DEFAULT[23]='N' # run it when execute_all is called -GROUP_CHECKS[23]='extra7115,extra7116,extra7117,extra7118,extra7120,extra7122' - From 6e604e1834b2886a49bb47565efd3c22990e2ccd Mon Sep 17 00:00:00 2001 From: Toni de la Fuente Date: Mon, 16 Nov 2020 17:51:53 +0100 Subject: [PATCH 13/13] Some corrections for glue related checks --- checks/check_extra7115 | 4 ++-- checks/check_extra7116 | 4 ++-- checks/check_extra7117 | 6 +++--- checks/check_extra7118 | 16 ++++++++++------ checks/check_extra7120 | 12 ++++++------ checks/check_extra7122 | 8 ++++---- groups/group24_glue | 18 ++++++++++++++++++ 7 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 groups/group24_glue diff --git a/checks/check_extra7115 b/checks/check_extra7115 index ad597b07..da606669 100644 --- a/checks/check_extra7115 +++ b/checks/check_extra7115 @@ -21,14 +21,14 @@ CHECK_ALTERNATE_check7115="extra7115" 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}') - if [[ ! -z "$CONNECTION_LIST" ]]; then + 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" else - textInfo "$regx: Glue connection $CONNECTION_NAME has SSL connection enabled" "$regx" + textPass "$regx: Glue connection $CONNECTION_NAME has SSL connection enabled" "$regx" fi done else diff --git a/checks/check_extra7116 b/checks/check_extra7116 index aa778774..2165b91a 100644 --- a/checks/check_extra7116 +++ b/checks/check_extra7116 @@ -22,9 +22,9 @@ extra7116(){ for regx in $REGIONS; do 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" + textFail "$regx: Glue data catalog settings have metadata encryption disabled" "$regx" else - textInfo "$regx: Glue data-catalog settings have metadata encryption enabled" "$regx" + textPass "$regx: Glue data catalog settings have metadata encryption enabled" "$regx" fi done } diff --git a/checks/check_extra7117 b/checks/check_extra7117 index cd8b66b5..7c11c76d 100644 --- a/checks/check_extra7117 +++ b/checks/check_extra7117 @@ -11,7 +11,7 @@ # 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_TITLE_extra7117="[extra7117] Check if Glue data catalog settings have encrypt connection password enabled." CHECK_SCORED_extra7117="NOT_SCORED" CHECK_TYPE_extra7117="EXTRA" CHECK_SEVERITY_extra7117="Medium" @@ -22,9 +22,9 @@ extra7117(){ for regx in $REGIONS; do 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 Catalog connection password is not encrypted" "$regx" + textFail "$regx: Glue data catalog connection password is not encrypted" "$regx" else - textInfo "$regx: Glue catalog connection password is encrypted" "$regx" + textPass "$regx: Glue data catalog connection password is encrypted" "$regx" fi done } diff --git a/checks/check_extra7118 b/checks/check_extra7118 index abc02ac7..aa39907f 100644 --- a/checks/check_extra7118 +++ b/checks/check_extra7118 @@ -10,8 +10,8 @@ # 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.117" -CHECK_TITLE_extra7118="[extra7118] Check if Glue security configurations used by ETL Jobs have S3 encryption enabled." +CHECK_ID_extra7118="7.118" +CHECK_TITLE_extra7118="[extra7118] Check if Glue ETL Jobs have S3 encryption enabled." CHECK_SCORED_extra7118="NOT_SCORED" CHECK_TYPE_extra7118="EXTRA" CHECK_SEVERITY_extra7118="Medium" @@ -21,7 +21,7 @@ CHECK_ALTERNATE_check7118="extra7118" 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"}') - if [[ ! -z "$JOB_LIST" ]]; then + 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') @@ -29,12 +29,16 @@ extra7118(){ 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 - textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" + if [[ ! -z "$JOB_ENCRYPTION" ]]; then + textPass "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION for S3 encryption enabled" "$regx" + else + textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" + fi else - textInfo "$regx: Glue job $JOB_NAME does have $S3_ENCRYPTION S3 encryption enabled" "$regx" + textPass "$regx: Glue job $JOB_NAME does have $S3_ENCRYPTION for S3 encryption enabled" "$regx" fi elif [[ ! -z "$JOB_ENCRYPTION" ]]; then - textInfo "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION S3 encryption enabled" "$regx" + textPass "$regx: Glue job $JOB_NAME does have $JOB_ENCRYPTION for S3 encryption enabled" "$regx" else textFail "$regx: Glue job $JOB_NAME does not have S3 encryption enabled" "$regx" fi diff --git a/checks/check_extra7120 b/checks/check_extra7120 index 32a6053b..69695b7f 100644 --- a/checks/check_extra7120 +++ b/checks/check_extra7120 @@ -10,8 +10,8 @@ # 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.117" -CHECK_TITLE_extra7120="[extra7120] Check if Glue security configurations used by ETL Jobs have CloudWatch logs encryption enabled." +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_TYPE_extra7120="EXTRA" CHECK_SEVERITY_extra7120="Medium" @@ -21,19 +21,19 @@ CHECK_ALTERNATE_check7120="extra7120" extra7120(){ for regx in $REGIONS; do JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}') - if [[ ! -z "$JOB_LIST" ]]; then + 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" + textFail "$regx: Glue job $JOB_NAME does not have CloudWatch Logs encryption enabled" "$regx" else - textInfo "$regx: Glue job $JOB_NAME does have $CLOUDWATCH_ENCRYPTION CloudWatch logs encryption enabled" "$regx" + textPass "$regx: Glue job $JOB_NAME does have $CLOUDWATCH_ENCRYPTION CloudWatch Logs encryption enabled" "$regx" fi else - textFail "$regx: Glue job $JOB_NAME does not have CloudWatch logs encryption enabled" "$regx" + textFail "$regx: Glue job $JOB_NAME does not have CloudWatch Logs encryption enabled" "$regx" fi done else diff --git a/checks/check_extra7122 b/checks/check_extra7122 index 3ea87a2d..618181c4 100644 --- a/checks/check_extra7122 +++ b/checks/check_extra7122 @@ -10,8 +10,8 @@ # 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.117" -CHECK_TITLE_extra7122="[extra7122] Check if Glue security configurations used by ETL Jobs have Job bookmark encryption enabled." +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_TYPE_extra7122="EXTRA" CHECK_SEVERITY_extra7122="Medium" @@ -21,7 +21,7 @@ CHECK_ALTERNATE_check7122="extra7122" extra7122(){ for regx in $REGIONS; do JOB_LIST=$($AWSCLI glue get-jobs $PROFILE_OPT --region $regx --output json --query 'Jobs[*].{Name:Name,SecurityConfiguration:SecurityConfiguration}') - if [[ $JOB_LIST ]]; then + 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') @@ -30,7 +30,7 @@ extra7122(){ if [[ "$JOB_BOOKMARK_ENCRYPTION" == "DISABLED" ]]; then textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" else - textInfo "$regx: Glue job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION Job bookmark encryption enabled" "$regx" + textPass "$regx: Glue job $JOB_NAME does have $JOB_BOOKMARK_ENCRYPTION for Job bookmark encryption enabled" "$regx" fi else textFail "$regx: Glue job $JOB_NAME does not have Job bookmark encryption enabled" "$regx" diff --git a/groups/group24_glue b/groups/group24_glue new file mode 100644 index 00000000..518a6f24 --- /dev/null +++ b/groups/group24_glue @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2020) 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. + +GROUP_ID[23]='glue' +GROUP_NUMBER[23]='23.0' +GROUP_TITLE[23]='Amazon Glue related security checks - [glue] ********' +GROUP_RUN_BY_DEFAULT[23]='N' # run it when execute_all is called +GROUP_CHECKS[23]='extra7115,extra7116,extra7117,extra7118,extra7120,extra7122'