Skip to main content

Unauthorized access to files - S3 Bucket

Need

Secure access control for S3 buckets

Context

  • Usage of Terraform for Infrastructure as Code (IaC)
  • Usage of aws_s3_bucket for interacting with Amazon S3 buckets

Description

Non compliant code

resource "aws_s3_bucket" "bucket" {
bucket = "mybucket"
acl = "public-read"
}

The above Terraform code is creating an AWS S3 bucket with the name "mybucket". The ACL (Access Control List) property is set to "public-read", which means the bucket is readable by anyone. This is a security vulnerability as it allows unauthorized users to access and download the content of this bucket without requiring any authentication.

The acl argument controls the permissions of the bucket. When it's set to "public-read", it grants READ access to any user, authenticated or not. This is a major security risk as it can lead to unauthorized data exposure, data loss, or even data corruption if an attacker decides to delete or modify the stored information.

In addition, if sensitive data is stored in this bucket, it could lead to a data breach, which could have significant legal and financial implications. Therefore, it's crucial to restrict the access to this bucket to only those who need it.

Steps

  • Remove the 'acl' attribute from the 'aws_s3_bucket' resource
  • Set the appropriate access control policies for the S3 bucket
  • Ensure that the bucket is not publicly accessible

Compliant code

resource "aws_s3_bucket" "bucket" {
bucket = "mybucket"
}

The above code defines an AWS S3 bucket resource using Terraform. The bucket is named "mybucket". The 'acl' attribute, which was previously set to "public-read", has been removed. This change is made to prevent public access to the bucket.

To further secure the bucket, you should define an AWS S3 bucket policy that specifies the necessary access controls. This policy should be attached to the bucket to ensure that only authorized users and services can access the bucket's content.

Here is an example of how you can define a bucket policy:

resource "aws_s3_bucket_policy" "bucket_policy" {
bucket = aws_s3_bucket.bucket.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
Resource = [
"${aws_s3_bucket.bucket.arn}/*"
]
},
]
})
}

In the above example, the bucket policy allows the root user of the AWS account to perform 'GetObject', 'PutObject', and 'DeleteObject' actions on the objects in the bucket. You should modify this policy according to your specific requirements.

Remember, it's crucial to ensure that your S3 buckets are not publicly accessible unless it's necessary for your use case. Publicly accessible buckets can lead to unauthorized access, data leakage, and potential data loss.

References