I am trying to create a predesigned POST
request using the AWS Javascript SDK for S3, using the method createPresignedPost
. The idea is to generate the URL and fields which should be used in a multipart form request, to upload a file to a protected S3 bucket. I would like to include checksum verification (whereby I pass in the expected SHA256 checksum of the file to the presigner, and the S3 server verifies that the checksum of the uploaded file corresponds to the one provided, so that only the originally specified file may be uploaded using this request) as well as to restrict the size of the upload.
I originally tried to follow this tutorial which seemed pretty comprehensive. However, this did not work (I kept on getting an error regarding the Content-MD5
header) and I eventually found that MD5 does not seem to be supported by S3 anymore. I also noticed that the presigner was including the field X-Amz-Algorithm=AWS4-HMAC-SHA256
which would seem to indicate that it is defaulting to SHA-256. However, sending the SHA256 hash with the same request did not solve the problem nor could I find any explicit way to tell the presigner which algorithm to use and what value to expect.
I cannot remember where I came across it, but I tried including:
{ ChecksumAlgorithm: ChecksumAlgorithm.SHA256 },
{ ChecksumSHA256: hash },
in my conditions but this did not work either.
I am not sure whether I am understanding this issue correctly, but it may even be that S3 does not support checksum verification for presigned POST
.
So, I suppose my questions come down to the following:
POST
?POST
(and if so, in which version)?POST
, restricting the uploaded file to correspond to the given checksum value?So for checksum parameters like ChecksumSHA256 or ChecksumAlgorithm are not directly supported in presigned POST requests. The SDK can handle checksums for other types of uploads, such as PutObject, where headers like x-amz-checksum-sha256
can be included, but not for presigned POST.
S3 checksum validation is designed for multipart uploads or for requests with the x-amz-checksum headers, you can't use them for the POST but checksum validation can be achieved by manually validating the uploaded object after it lands in the bucket (using Lambda for example).
this is an ecample of lambda code to check the checksum after the upload:
const validateChecksum = async (bucketName, key, expectedChecksum) => {
const client = new S3Client({ region: 'eu-central-1' });
try {
const response = await client.send(
new HeadObjectCommand({
Bucket: bucketName,
Key: key,
})
);
const actualChecksum = response.ChecksumSHA256;
if (actualChecksum === expectedChecksum) {
console.log('Checksum validation passed!');
} else {
console.error('Checksum validation failed!');
}
} catch (error) {
console.error('Error validating checksum:', error);
}
};
and you can restrict the size of the file being uploaded using the content-length-range
condition in the policy of the presigned POST request. This condition enforces a size range for the file uploaded to S3. here's the documentation for that : https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html