Skip to main content

Unauthorized access to files - S3 Bucket

Description

Some buckets used by the application can be publicly accessed, without requiring any authentication, allowing an attacker to download its content, modify or delete the stored information

Impact

Compromise the information stored in the buckets.

Recommendation

Restrict the access of the public buckets of the system

Threat

Anonymous attacker from the Internet.

Expected Remediation Time

⌚ 15 minutes.

Score

Default score using CVSS 3.1. It may change depending on the context of the vulnerability.

Base

  • Attack vector: N
  • Attack complexity: L
  • Privileges required: N
  • User interaction: N
  • Scope: U
  • Confidentiality: H
  • Integrity: N
  • Availability: N

Temporal

  • Exploit code madurity: X
  • Remediation level: X
  • Report confidence: X

Result

  • Vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N/E:X/RL:X/RC:X
  • Score:
    • Base: 7.5
    • Temporal: 7.5
  • Severity:
    • Base: High
    • Temporal: High

Code Examples

Compliant code

All AWS buckets have restricted permissions only accesible to authorized users

Resources:
PrivateS3Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
BucketName: SKIMS-PRIVATE-BUCKET
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
KMSMasterKeyID: KMS-KEY-ARN
DeletionPolicy: Delete

Terraform example

resource "aws_s3_bucket" "test" {
bucket = "my-tf-test-bucket"
acl = "log-delivery-write"

logging {
target_bucket = aws_s3_bucket.log_bucket.id
target_prefix = "log/"
}
}

Non compliant code

An S3 AWS bucket has public permissions to allow deletion of files

Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: PublicReadWrite
BucketName: SKIMS-PUBLIC-BUCKET-2
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
KMSMasterKeyID: KMS-KEY-ARN
DeletionPolicy: Delete

Terraform example

resource "aws_s3_bucket" "example" {
bucket = "s3-website-test.hashicorp.com"
acl = "public-read-write"

cors_rule {
allowed_headers = ["*"]
allowed_methods = ["PUT", "POST"]
allowed_origins = ["https://s3-website-test.hashicorp.com"]
expose_headers = ["ETag"]
max_age_seconds = 3000
}
}

Using the AWS CLI, the following command returns the S3 bucket ACL configuration

$ aws s3api get-bucket-acl
--bucket {bucket_id}
--query 'Grants[?(Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers`)]'

If the command output returns "FULL_CONTROL" for the "Permission" attribute, the bucket is publicly accessible and insecure

Requirements