mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
159 lines
7.7 KiB
Bash
159 lines
7.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_extra73="7.3"
|
|
CHECK_TITLE_extra73="[extra73] Ensure there are no S3 buckets open to Everyone or Any AWS user"
|
|
CHECK_SCORED_extra73="NOT_SCORED"
|
|
CHECK_TYPE_extra73="EXTRA"
|
|
CHECK_SEVERITY_extra73="Critical"
|
|
CHECK_ASFF_RESOURCE_TYPE_extra73="AwsS3Bucket"
|
|
CHECK_ALTERNATE_extra703="extra73"
|
|
CHECK_ALTERNATE_check73="extra73"
|
|
CHECK_ALTERNATE_check703="extra73"
|
|
CHECK_SERVICENAME_extra73="s3"
|
|
CHECK_RISK_extra73='Even if you enable all possible bucket ACL options available in the Amazon S3 console the ACL alone does not allow everyone to download objects from your bucket. Depending on which option you select any user could perform some actions.'
|
|
CHECK_REMEDIATION_extra73='You can enable block public access settings only for access points; buckets; and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account; the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously; but they eventually propagate to all Regions.'
|
|
CHECK_DOC_extra73='https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html'
|
|
CHECK_CAF_EPIC_extra73='Data Protection'
|
|
|
|
# Verified with AWS support that if get-bucket-acl doesn't return a grant
|
|
# for All and get-bucket-policy-status returns IsPublic false or bad request
|
|
# (no policy) then the bucket can be considered not public - though
|
|
# individual objects may still be. If in addition put-public-access-block is
|
|
# used to set IgnorePublicAcls and RestrictPublicBuckets to true then that
|
|
# causes Amazon S3 to ignore all public ACLs on a bucket and any objects that
|
|
# it contains.
|
|
#
|
|
# This check does not address legacy ACLs or policies that would give
|
|
# public access if not blocked at account or bucket level, instead it tries
|
|
# to reward the use of more broadly restrictive controls with quicker and less
|
|
# computational intensive checks.
|
|
#
|
|
# If we are assembling an inventory then maybe that is not what we want but
|
|
# for day to day usage that is probably desirable.
|
|
|
|
extra73(){
|
|
#
|
|
# If public ACLs disabled at account level then look no further
|
|
#
|
|
ACCOUNT_PUBLIC_ACCESS_BLOCK=$($AWSCLI s3control get-public-access-block $PROFILE_OPT --region $REGION --account-id $ACCOUNT_NUM --output json 2>&1)
|
|
if [[ $(echo "$ACCOUNT_PUBLIC_ACCESS_BLOCK" | grep AccessDenied) ]]; then
|
|
textFail "$REGION: Access Denied getting PublicAccessBlock configuration for AWS account" "$REGION" "$bucket"
|
|
return
|
|
fi
|
|
if [[ $(echo "$ACCOUNT_PUBLIC_ACCESS_BLOCK" | grep NoSuchPublicAccessBlockConfiguration) ]]; then
|
|
ACCOUNTIGNOREPUBLICACLS=""
|
|
ACCOUNTRESTRICTPUBLICBUCKETS=""
|
|
else
|
|
ACCOUNTIGNOREPUBLICACLS=$(echo "$ACCOUNT_PUBLIC_ACCESS_BLOCK" | jq -r '.PublicAccessBlockConfiguration.IgnorePublicAcls')
|
|
ACCOUNTRESTRICTPUBLICBUCKETS=$(echo "$ACCOUNT_PUBLIC_ACCESS_BLOCK" | jq -r '.PublicAccessBlockConfiguration.RestrictPublicBuckets')
|
|
fi
|
|
if [[ $ACCOUNTIGNOREPUBLICACLS == "true" && $ACCOUNTRESTRICTPUBLICBUCKETS == "true" ]]; then
|
|
textPass "$REGION: All S3 public access blocked at account level" "$REGION" "$bucket"
|
|
return
|
|
fi
|
|
|
|
#
|
|
# Otherwise start to iterate bucket
|
|
#
|
|
ALL_BUCKETS_LIST=$($AWSCLI s3api list-buckets --query 'Buckets[*].{Name:Name}' $PROFILE_OPT --output text 2>&1)
|
|
if [[ $(echo "$ALL_BUCKETS_LIST" | grep AccessDenied) ]]; then
|
|
textFail "$REGION: Access Denied Trying to List Buckets" "$REGION" "$bucket"
|
|
return
|
|
fi
|
|
if [[ "$ALL_BUCKETS_LIST" == "" ]]; then
|
|
textInfo "$REGION: No buckets found" "$REGION" "$bucket"
|
|
return
|
|
fi
|
|
|
|
for bucket in $ALL_BUCKETS_LIST; do
|
|
|
|
#
|
|
# LOCATION - requests referencing buckets created after March 20, 2019
|
|
# must be made to S3 endpoints in the same region as the bucket was
|
|
# created.
|
|
#
|
|
BUCKET_LOCATION=$($AWSCLI s3api get-bucket-location $PROFILE_OPT --region $REGION --bucket $bucket --output text 2>&1)
|
|
if [[ $(echo "$BUCKET_LOCATION" | grep AccessDenied) ]]; then
|
|
textFail "$REGION: Access Denied Trying to Get Bucket Location for $bucket" "$REGION" "$bucket"
|
|
continue
|
|
fi
|
|
if [[ $BUCKET_LOCATION == "None" ]]; then
|
|
BUCKET_LOCATION="us-east-1"
|
|
fi
|
|
if [[ $BUCKET_LOCATION == "EU" ]]; then
|
|
BUCKET_LOCATION="eu-west-1"
|
|
fi
|
|
#
|
|
# If public ACLs disabled at bucket level then look no further
|
|
#
|
|
BUCKET_PUBLIC_ACCESS_BLOCK=$($AWSCLI s3api get-public-access-block $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --output json 2>&1)
|
|
if [[ $(echo "$BUCKET_PUBLIC_ACCESS_BLOCK" | grep AccessDenied) ]]; then
|
|
textFail "$BUCKET_LOCATION: Access Denied Trying to Get Public Access Block for $bucket" "$BUCKET_LOCATION" "$bucket"
|
|
continue
|
|
fi
|
|
if [[ $(echo "$BUCKET_PUBLIC_ACCESS_BLOCK" | grep NoSuchPublicAccessBlockConfiguration) ]]; then
|
|
BUCKETIGNOREPUBLICACLS=""
|
|
BUCKETRESTRICTPUBLICBUCKETS=""
|
|
else
|
|
BUCKETIGNOREPUBLICACLS=$(echo "$BUCKET_PUBLIC_ACCESS_BLOCK" | jq -r '.PublicAccessBlockConfiguration.IgnorePublicAcls')
|
|
BUCKETRESTRICTPUBLICBUCKETS=$(echo "$BUCKET_PUBLIC_ACCESS_BLOCK" | jq -r '.PublicAccessBlockConfiguration.RestrictPublicBuckets')
|
|
fi
|
|
if [[ $BUCKETIGNOREPUBLICACLS == "true" && $BUCKETRESTRICTPUBLICBUCKETS == "true" ]]; then
|
|
textPass "$BUCKET_LOCATION: $bucket bucket is not Public" "$BUCKET_LOCATION" "$bucket"
|
|
continue
|
|
fi
|
|
|
|
#
|
|
# Check for public ACL grants
|
|
#
|
|
BUCKET_ACL=$($AWSCLI s3api get-bucket-acl $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --output json 2>&1)
|
|
if [[ $(echo "$BUCKET_ACL" | grep AccessDenied) ]]; then
|
|
textFail "$BUCKET_LOCATION: Access Denied Trying to Get Bucket Acl for $bucket" "$BUCKET_LOCATION" "$bucket"
|
|
continue
|
|
fi
|
|
|
|
ALLUSERS_ACL=$(echo "$BUCKET_ACL" | jq '.Grants[]|select(.Grantee.URI != null)|select(.Grantee.URI | endswith("/AllUsers"))')
|
|
if [[ $ALLUSERS_ACL != "" ]]; then
|
|
textFail "$BUCKET_LOCATION: $bucket bucket is Public!" "$BUCKET_LOCATION" "$bucket"
|
|
continue
|
|
fi
|
|
|
|
AUTHENTICATEDUSERS_ACL=$(echo "$BUCKET_ACL" | jq '.Grants[]|select(.Grantee.URI != null)|select(.Grantee.URI | endswith("/AuthenticatedUsers"))')
|
|
if [[ $AUTHENTICATEDUSERS_ACL != "" ]]; then
|
|
textFail "$BUCKET_LOCATION: $bucket bucket is Public!" "$BUCKET_LOCATION" "$bucket"
|
|
continue
|
|
fi
|
|
|
|
#
|
|
# Check for public access in policy
|
|
#
|
|
BUCKET_POLICY_STATUS=$($AWSCLI s3api get-bucket-policy-status $PROFILE_OPT --region $BUCKET_LOCATION --bucket $bucket --query PolicyStatus.IsPublic --output text 2>&1)
|
|
if [[ $(echo "$BUCKET_POLICY_STATUS" | grep AccessDenied) ]]; then
|
|
textFail "$BUCKET_LOCATION: Access Denied Trying to Get Bucket Policy Status for $bucket" "$BUCKET_LOCATION" "$bucket"
|
|
continue
|
|
fi
|
|
if [[ $(echo "$BUCKET_POLICY_STATUS" | grep NoSuchBucketPolicy) ]]; then
|
|
BUCKET_POLICY_STATUS="False"
|
|
fi
|
|
|
|
if [[ $BUCKET_POLICY_STATUS != "" && $BUCKET_POLICY_STATUS != "False" ]]; then
|
|
textFail "$BUCKET_LOCATION: $bucket bucket is Public!" "$BUCKET_LOCATION" "$bucket"
|
|
continue
|
|
fi
|
|
|
|
textPass "$BUCKET_LOCATION: $bucket bucket is not Public" "$BUCKET_LOCATION" "$bucket"
|
|
|
|
done
|
|
}
|