Files
prowler/checks/check_extra771
Leonardo Azize Martins 248cc9d68b Fix(extra771): jq fail when policy action is an array (#1031)
* Fix error handling and policy output

* Fix jq filter when Action is an array

Fix jq select condition to handle Action as string or as array.
Add error handling.
When fail, print policies as just one line.

* Double quote variables to prevent globbing and word splitting

* Replace comma character from json by word comma
2022-03-02 15:04:18 +01:00

69 lines
5.7 KiB
Bash

#!/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_extra771="7.71"
CHECK_TITLE_extra771="[extra771] Check if S3 buckets have policies which allow WRITE access "
CHECK_SCORED_extra771="NOT_SCORED"
CHECK_CIS_LEVEL_extra771="EXTRA"
CHECK_SEVERITY_extra771="Critical"
CHECK_ASFF_RESOURCE_TYPE_extra771="AwsS3Bucket"
CHECK_ALTERNATE_check771="extra771"
CHECK_SERVICENAME_extra771="s3"
CHECK_RISK_extra771='Non intended users can put objects in a given bucket.'
CHECK_REMEDIATION_extra771='Ensure proper bucket policy is in place with the least privilege principle applied.'
CHECK_DOC_extra771='https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_rw-bucket.html'
CHECK_CAF_EPIC_extra771='IAM'
extra771(){
LIST_OF_BUCKETS=$("${AWSCLI}" s3api list-buckets $PROFILE_OPT --region "${REGION}" --query "sort_by(Buckets, &Name)[].Name" --output text 2>&1)
if [[ $(echo "${LIST_OF_BUCKETS}" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "${REGION}: Access Denied trying to list buckets" "${REGION}"
return
fi
if [[ "${LIST_OF_BUCKETS}" ]]; then
for bucket in ${LIST_OF_BUCKETS};do
BUCKET_POLICY_STATEMENTS=$("${AWSCLI}" s3api $PROFILE_OPT get-bucket-policy --region "${REGION}" --bucket "${bucket}" --output json --query Policy 2>&1)
if [[ $(echo "${BUCKET_POLICY_STATEMENTS}" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "${REGION}: Access Denied trying to get bucket policy for ${bucket}" "${REGION}"
continue
fi
if [[ $(echo "${BUCKET_POLICY_STATEMENTS}" | grep 'NoSuchBucketPolicy') ]]; then
textInfo "$REGION: Bucket policy does not exist for bucket $bucket" "$REGION"
else
BUCKET_POLICY_BAD_STATEMENTS=$(echo "${BUCKET_POLICY_STATEMENTS}" | jq --compact-output --arg arn "arn:${AWS_PARTITION}:s3:::$bucket" 'fromjson | .Statement[]|select(
.Effect=="Allow" and
(
( (.Principal|type == "object") and (.Principal.AWS == "*") ) or
( (.Principal|type == "string") and (.Principal == "*") )
) and
(
( (.Action|type == "string") and (.Action|startswith("s3:Put")) ) or
( (.Action|type == "string") and (.Action|startswith("s3:*")) ) or
( (.Action|type == "array") and (.Action[]|startswith("s3:Put")) ) or
( (.Action|type == "array") and (.Action[]|startswith("s3:*")) )
) and
.Condition == null
)' | tr '\n' ' ')
# Make sure JSON comma characted will not break CSV output. Replace "," by word "[comma]"
BUCKET_POLICY_BAD_STATEMENTS="${BUCKET_POLICY_BAD_STATEMENTS//,/[comma]}"
if [[ "${BUCKET_POLICY_BAD_STATEMENTS}" != "" ]]; then
textFail "${REGION}: Bucket ${bucket} allows public write: ${BUCKET_POLICY_BAD_STATEMENTS}" "${REGION}" "${bucket}"
else
textPass "${REGION}: Bucket ${bucket} has S3 bucket policy which does not allow public write access" "${REGION}" "${bucket}"
fi
fi
done
else
textInfo "${REGION}: No S3 Buckets found"
fi
}