What S3 bucket policy can I use to comply with the AWS Config rule s3-bucket-ssl-requests-only?

2 minute read
1

I activated the AWS Config rule “s3-bucket-ssl-requests-only” for Amazon Simple Storage Service (Amazon S3) bucket policies to require encryption during data transit. I want to make sure that my bucket policies comply with this rule.

Resolution

Note: Amazon S3 offers encryption in transit and encryption at rest. Encryption in transit refers to HTTPS, and encryption at rest refers to client-side or server-side encryption.

Amazon S3 allows both HTTP and HTTPS requests. By default, Amazon S3 makes requests through the AWS Management Console, the AWS Command Line Interface (AWS CLI), or HTTPS.

To comply with the s3-bucket-ssl-requests-only rule, confirm that your bucket policies explicitly deny access to HTTP requests. Bucket policies that allow HTTPS requests but don't explicitly deny HTTP requests might not comply with the rule.

To determine HTTP or HTTPS requests in a bucket policy, use a condition that checks for the key "aws:SecureTransport". When this key is true, then Amazon S3 sends the request through HTTPS. To comply with the s3-bucket-ssl-requests-only rule, create a bucket policy that explicitly denies access when the request meets the condition "aws:SecureTransport": "false". This policy explicitly denies access to HTTP requests.

Bucket policy that complies with s3-bucket-ssl-requests-only rule

This example bucket policy complies with the s3-bucket-ssl-requests-only rule. This policy explicitly denies all actions on the bucket and objects when the request meets the condition "aws:SecureTransport": "false":

{
  "Id": "ExamplePolicy",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowSSLRequestsOnly",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      },
      "Principal": "*"
    }
  ]
}

Bucket policy that doesn't comply with s3-bucket-ssl-requests-only rule

This bucket policy doesn't comply with the s3-bucket-ssl-requests-only rule. Instead of an explicit deny statement, the policy allows access to requests that meet the condition "aws:SecureTransport": "true". This statement allows anonymous access to s3:GetObject for all objects in the bucket if the request uses HTTPS. Avoid this type of bucket policy unless your use case requires anonymous access through HTTPS:

{
  "Id": "ExamplePolicy",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "NOT-RECOMMENDED-FOR__AWSCONFIG-Rule_s3-bucket-ssl-requests-only",
      "Action": "s3:GetObject",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "true"
        }
      },
      "Principal": "*"
    }
  ]
}

Related information

How to use bucket policies and apply defense-in-depth to help secure your Amazon S3 data

AWS OFFICIAL
AWS OFFICIALUpdated a year ago
19 Comments

Does it matter if it is set to string "false" or actual boolean false?

AWS
Rt
replied 2 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 2 years ago

When I try to apply this policy, I get an error stating that it grants a level of public access that conflicts with my "Block Public Access" settings. I have "Block all public access" set, but I also want to block access from insecure transports. How can I enforce HTTPS for restapi requests?

abh555
replied 2 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 2 years ago

For the second example, where we allow public access with GetObject, to remain compliant with AWS Config s3-bucket-ssl-requests-only rule, we have to also include the first example as the second statement, so deny anything that is not secureTransport.

ppab-sp
replied a year ago

Hi Team,

For the "Deny" & "aws:SecureTransport":"true" example, under the actions section there is s3.* rather can we be more specific on what actions are actually required for this aws:SecureTransport to work?

replied a year ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied a year ago

Does it matter if it is set to string "false" or actual boolean false?

yes, the bucket policy supports JSON so it should be a string i.e. "false"

AWS
SUPPORT ENGINEER
replied a year ago

For the second example, where we allow public access with GetObject, to remain compliant with AWS Config s3-bucket-ssl-requests-only rule, we have to also include the first example as the second statement, so deny anything that is not secureTransport.

The second policy is not complying with ssl only requests. Instead the statement allows anonymous access to s3:GetObject for all objects in the bucket if the request uses HTTPS.

AWS
SUPPORT ENGINEER
replied a year ago
AWS
SUPPORT ENGINEER
replied a year ago

Note that instead of manually creating a policy and attaching it to a bucket, S3Bucket CDK construct supports a single flag enforceSSL: true which will do that for you. See https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html#enforcessl

AWS
Alex
replied 10 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 10 months ago

Would it be possible to show how we can implement this solution using AWS CDK?

EDIT: If anyone comes across this thread before the article is updated this is the solution I ended up with. Note that I don't understand the Principals part of this. I tried to use new AnyPrincipal() which I saw several examples of, but this gave me access denied error. If what I've done makes sense, maybe someone who understands it better could explain the implementation.

My comment was too long to post in one comment, so the code is in a comment below

EDIT2: I just realized from Alex's answer above that including the EnforceSSL = true in my code below is redundant when also adding the resource policy. Would be nice to get this confirmed/refute this.

replied 6 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 6 months ago
var myBucket = new Bucket(this, "MyBucket", new BucketProps
        {
            BucketName = $"bucket-name",
            EnforceSSL = true
        });

        // Define the bucket policies to deny non-HTTPS connections and allow read access to all objects
        myBucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps
        {
            Actions = ["s3:*"],
            Effect = Effect.DENY,
            Principals = [new ServicePrincipal("s3.amazonaws.com")],
            Resources = [myBucket .BucketArn + "/*"],
            Conditions = new Dictionary<string, object>
            {
                { "Bool", new Dictionary<string, object> { { "aws:SecureTransport", false } } }
            }
        }));

        myBucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps
        {
            Actions = ["s3:GetObject"],
            Effect = Effect.ALLOW,
            Principals = [new ServicePrincipal("s3.amazonaws.com")],
            Resources = [myBucket.BucketArn + "/*"],
            Conditions = new Dictionary<string, object>
            {
                { "Bool", new Dictionary<string, object> { { "aws:SecureTransport", true } } }
            }
        }));```
replied 6 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 6 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 8 days ago