diff --git a/checks/check_extra771 b/checks/check_extra771 index 243d6441..fb3a6a29 100644 --- a/checks/check_extra771 +++ b/checks/check_extra771 @@ -24,23 +24,45 @@ CHECK_DOC_extra771='https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_p CHECK_CAF_EPIC_extra771='IAM' extra771(){ - LIST_OF_BUCKETS=$($AWSCLI s3api list-buckets $PROFILE_OPT --region $REGION --query Buckets[*].Name --output text|xargs -n1) - 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 [[ $BUCKET_POLICY_STATEMENTS == *GetBucketPolicy* ]]; then - textInfo "Bucket policy does not exist for bucket $bucket" + 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 --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|startswith("s3:Put") or startswith("s3:*")) and .Condition == null)') - if [[ $BUCKET_POLICY_BAD_STATEMENTS != "" ]]; then - textFail "Bucket $bucket allows public write: $BUCKET_POLICY_BAD_STATEMENTS" "us-east-1" "$bucket" + 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 "Bucket $bucket has S3 bucket policy which does not allow public write access" "us-east-1" "$bucket" + textPass "${REGION}: Bucket ${bucket} has S3 bucket policy which does not allow public write access" "${REGION}" "${bucket}" fi fi done - else - textInfo "No S3 Buckets found" + textInfo "${REGION}: No S3 Buckets found" fi }