Content Type not enforced in s3 pre-signed POST
Asked Answered
P

3

12

I'm currently using the AWS javascript SDK to create pre-signed POST's. (note that this question is NOT about pre-signed PUTs/URLs, another s3 feature)

https://github.com/aws/aws-sdk-js/

When trying to create a pre-signed post I do something like the following:

const params = {
  Bucket: 'myuniques3bucket',
  Fields: {
    Key: 'key1.png',
    'Content-Type': 'image/png'
  },
  conditions: [
    {bucket: 'myuniques3bucket'},
    {key: 'key1.png'},
    {'Content-Type': 'image/png'},
    ['content-length-range', 1024, 1048576], // 1KB to 10MB
    {'x-amz-date': amzDate},
    {'x-amz-algorithm': 'AWS4-HMAC-SHA256'},
    {'x-amz-credential': `${process.env.AWS_ACCESS_KEY_ID}/20180820/us-east-2/s3/aws4_request`}
  ],
  Expires: 300  // 300 seconds
}

s3.createPresignedPost(params, (err, data) => {
  console.log(data);
});

And I'm wrapping tests around the upload processes that should not work. I'm finding that the content type is not enforced there as I can upload other file types with other content-type post params.

It's not clear to me whether the JS SDK manages the signing process for the user or if I need to do something special to get these various keys in the signature.

It's clear that I CAN do some of this, it's not clear if I NEED to. Not sure if the library is supposed to be handling that for me.

TLDR; What do I need to do to activate content-type validation with s3 pre-signed POST's using the js sdk?

Any help would be greatly appreciated.

Pinion answered 20/8, 2018 at 17:24 Comment(1)
i am facing the same problem did you manage to make it workTrestle
C
9

The policy document is only specifying what the form fields must contain in order for S3 to accept the signed request as valid -- in this case, that the form must claim that the content-type is image/png so that S3 will store the object with Content-Type: image/png. This mechanism doesn't actually validate the content-type of the object itself. S3 doesn't have a way of doing that, nor does the JS SDK.

You could do it in JS in the browser or you could do it after the upload, using an S3 event to notify a background process that the uploaded content needs to be validated. Post-processing images is probably a good practice, anyway, because you often want to strip out any inappropriate metadata, such as data included in some images identifying the location where the photo was taken.

Cletis answered 20/8, 2018 at 20:57 Comment(3)
To clarify, the form I'm submitting claims that the content type is something else. In this case I'm claiming that it's text/plain and the upload still works and I expect it not to. Understood that S3/sdk doesn't open the file and actually verify the type your form claims. This is why I'm wondering if it's ignoring content-type or if I'm just not signing the request correctly or something.Pinion
Interesting. That should not be possible. What about the object? What content-type do you see if you inspect it in the console after the upload?Cletis
I noticed the same behaviour: as long as the form provides a field named Content-Type with the value required by the policy, S3 will accept the file, whatever its contents.Unnecessarily
A
0

S3 Presigned Post is working as intended, even if it may look like it's not.

The file extension doesn't matter and neither does the actual Content-Type of the file in the multipart request; S3 ignores all of that.

However, the Content-Type we pass in the multipart request is validated against the Conditions and set as Content-Type metadata in the S3 Object. Any download of the S3 Object will present this metadata as the Content-Type in the response headers.

If the file extension matters to you (it doesn't to the web), you can enforce it by following the re:Post article

Arctic answered 21/6 at 14:43 Comment(0)
S
-2

You can just set your S3 storage to just accept certain types of files. Look at the docs: https://aws.amazon.com/premiumsupport/knowledge-center/s3-allow-certain-file-types/

Specht answered 17/4, 2020 at 2:31 Comment(1)
This link allows you to limit file names uploaded to only being those extensions. This will not check the actual content-type of the file. e.g. I upload a shell script with the extension shell-script.png, this would not fail.Bainbrudge

© 2022 - 2024 — McMap. All rights reserved.