mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 06:45:08 +00:00
79 lines
4.6 KiB
Bash
79 lines
4.6 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 grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${LIST_OF_BUCKETS}"; then
|
|
textInfo "${REGION}: Access Denied trying to list buckets" "${REGION}"
|
|
return
|
|
fi
|
|
if [[ "${LIST_OF_BUCKETS}" ]]; then
|
|
for bucket in ${LIST_OF_BUCKETS};do
|
|
# Recover Bucket region
|
|
BUCKET_REGION=$("${AWSCLI}" ${PROFILE_OPT} s3api get-bucket-location --bucket "${bucket}" --query LocationConstraint --output text)
|
|
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${BUCKET_POLICY_STATEMENTS}"; then
|
|
textInfo "${REGION}: Access Denied trying to get bucket policy for ${bucket}" "${REGION}"
|
|
fi
|
|
# If None use default region
|
|
if [[ "${BUCKET_REGION}" == "None" ]]; then
|
|
BUCKET_REGION="${REGION}"
|
|
fi
|
|
# Recover Bucket policy statements
|
|
BUCKET_POLICY_STATEMENTS=$("${AWSCLI}" s3api ${PROFILE_OPT} get-bucket-policy --region "${BUCKET_REGION}" --bucket "${bucket}" --output json --query Policy 2>&1)
|
|
if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "${BUCKET_POLICY_STATEMENTS}"; then
|
|
textInfo "${REGION}: Access Denied trying to get bucket policy for ${bucket}" "${REGION}"
|
|
continue
|
|
fi
|
|
if grep -q -E 'NoSuchBucketPolicy'<<< "${BUCKET_POLICY_STATEMENTS}"; then
|
|
textInfo "${REGION}: Bucket policy does not exist for bucket ${bucket}" "${REGION}"
|
|
else
|
|
BUCKET_POLICY_BAD_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
|
|
)' <<< "${BUCKET_POLICY_STATEMENTS}" | 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" "${REGION}"
|
|
fi
|
|
}
|