aws-sdk-js
aws-sdk-js copied to clipboard
getSignedUrl - POST support
In S3, direct-upload through pre-signed url don't have params for limiting the size of upload content, since it seems to be only valid for POST, not PUT.
This allows users to upload files that are much larger than expected. Attackers can bypass front-end check. Post-treatment does not seem to be an efficient practice.
I found some posts about such a feature (#1252 and #643), but they were abandoned and closed a few years ago.
However, support in python (boto3), Java and Go cli is mentioned.
I would like to apply the "content-length-range" in Conditions, as I can do in boto3.
Is there any possibility of implementing POST in aws-sdk-js and therefore these additional conditions ?
Thank you!
This is quite appalling that something as important as this has gone under the radar and is not being actively developed.
Is it possible to call createPresignedPost for 'uploadPart'? I try to create a large file loading system that generates signed links for each party, but to add security I need to indicate the size of each part (Content-Length).
I think It is possible now by using: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_s3_presigned_post.html
Thank you @mjpolak, it worked. Here's an example of usage:
Server code
import { createPresignedPost } from '@aws-sdk/s3-presigned-post'
import { S3Client } from '@aws-sdk/client-s3'
const client = new S3Client({
region: 'us-east-1',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID as string,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string,
},
})
async function GeneratePreSigned () {
const filename = 'image.png'
const Bucket = 'myucket'
const Key = 'images/' + filename
const Expires = 900 // 15 minutes
const Fields = {
acl: 'public-read',
}
const Conditions = [
{ acl: 'public-read' },
{ bucket: Bucket },
['starts-with', '$key', Key],
['content-length-range', 0, 1024 * 1024 * 5], // max 5MB
]
const { url, fields } = await createPresignedPost(client, {
Bucket,
Key,
Conditions,
Fields,
Expires,
})
return { url, fields }
}
Client example with React
<form action={url} method="post" encType="multipart/form-data">
{Object.keys(fields).map(key => (
<input type="hidden" name={key} value={fields[key]} />
))}
File:
<input type="file" name="file" />
<input type="submit" name="submit" value="Upload to Amazon S3" />
</form>