joe
joe

Reputation: 1713

Restricting file types on amazon s3 bucket with a policy

I'm trying to set up so the only file types the bucket can hold would be png, jpeg, and gif images. I'm trying to put in a bucket policy like this

{
    "conditions": [
        {"bucket": "bucketname"},
        ["starts-with", "$Content-Type", "image/jpeg"],
        ["starts-with", "$Content-Type", "image/png"],
        ["starts-with", "$Content-Type", "image/gif"],
        ["content-length-range", 0, 10485760]
    ]
}

Then I'm also trying to limit the size but when I try to update my policy I get the error "Invalid policy element - conditions"

I tried using the answer from here - s3 direct upload restricting file size and type so that's where I made my code from but I'm not sure the correct approach to do this since my policy isn't even being accepted by amazon.

Upvotes: 16

Views: 23486

Answers (2)

Robin He
Robin He

Reputation: 3389

I talked with AWS support engineer, the conditions.starts-with restriction is only supported by HTTP POST policy (eg: policy for browser form-field upload request). With this policy, it should be impossible to limit mineType when you or your users upload files with HTTP PUT request.

Reference: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html#sigv4-PolicyConditions.

For common policy, you can see available Condition keys here, https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazons3.html

And I find there is another solution which can restrict mineType,

  1. specify mineType for your html element, like this: <input type="file" accept="image/bmp,image/jpeg,image/png,image/gif"/>
  2. then you can get bmp, jpeg, png and gif through code, and you can set them as file URL extension of S3 object before upload.
  3. Finally you can add general policy to limit file URL extension like below. Reference: https://aws.amazon.com/premiumsupport/knowledge-center/s3-allow-certain-file-types/
{
    "Id": "Policy1464968545158",
    "Version": "2012-10-17",
    "Statement": [
      {
          "Sid": "Stmt1464968483619",
          "Effect": "Allow",
          "Principal": {
              "AWS": "IAM-USER-ARN"
          },
          "Action": "s3:PutObject",
          "Resource": [
              "arn:aws:s3:::bucket-name/*.bmp",
              "arn:aws:s3:::bucket-name/*.jpeg",
              "arn:aws:s3:::bucket-name/*.png",
              "arn:aws:s3:::bucket-name/*.gif"
         ]
     }
  ]
}
  1. So that you restrict the mimeType from browser side

Upvotes: 2

Frederic Henri
Frederic Henri

Reputation: 53733

You can use the policy generator for this if you're not sure how to write, for example you would have something like

{
  "Id": "Policy1464968545158",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1464968483619",
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::<yourbucket>/*.jpg",
      "Principal": "*"
    },
    {
      "Sid": "Stmt1464968543787",
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::<yourbucket>/*.png",
      "Principal": "*"
    }
  ]
}

As said from doc you can specify multiple resources and aggregate this part, so no need to multiply the statement

    "Resource": [
      "arn:aws:s3:::<yourbucket>/*.jpg",
      "arn:aws:s3:::<yourbucket>/*.png",
      "arn:aws:s3:::<yourbucket>/*.gif",
    ],

so you get something like

{
    "Id": "Policy1464968545158",
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "Stmt1464968483619",
        "Action": [
          "s3:PutObject"
        ],
        "Effect": "Allow",
        "Resource": [
          "arn:aws:s3:::<yourbucket>/*.jpg",
          "arn:aws:s3:::<yourbucket>/*.png",
          "arn:aws:s3:::<yourbucket>/*.gif",
        ],
        "Principal": "*"
      }
    ]
}

you can access policy generator when you create your bucket policy

enter image description here

Upvotes: 14

Related Questions