I am using S3 to accept direct uploads from the user to S3. Therefore I will be using pre-signed urls.
After successful upload, AWS Lambda will make sure that the file upload is an image, and then the client will tell my server that he has finished uploading.
Then my server will check if that file exists in S3 (if Lambda detects an invalid image, it deletes it). If it does, then the rest of the application logic will follow.
However, there is a loophole in this mechanism. A user can use the same url to upload a malicious file after telling my server that he has finished uploading (and initially passing a valid file).
Lambda will still delete the file, but now my server will think that a file exists whereas it actually does not.
Is there any way to generate a one-time upload pre-signed url, or is it possible to forcefully invalidate a url that was generated but has not yet expired?
The presigned URLs are valid only for the specified duration. If you created a presigned URL using a temporary token, then the URL expires when the token expires, even if the URL was created with a later expiration time. Anyone who receives the presigned URL can then access the object.
It grants restricted access — only one of GET or PUT is allowed for a single URL. Only to a single object — each pre-signed URL corresponds to one object. With a time-constrained — the URL expires after a set timeout.
The URL expires even if the URL was created with a later expiration time. The credentials that you can use to create a presigned URL include: AWS Identity and Access Management (IAM) instance profile: Valid up to six hours.
A presigned URL is a URL that you can provide to your users to grant temporary access to a specific S3 object. Using the URL, a user can either READ the object or WRITE an Object (or update an existing object). The URL contains specific parameters which are set by your application.
A pre-signed URL expires at a set date/time. It is not possible to create a one-time use pre-signed URL.
It is also not possible to invalidate a pre-signed URL. However, the pre-signed URL uses permissions from the Access Key that is referenced by the pre-signed URL. If permissions are removed from the User linked to the Access Key, then the pre-signed URL will not work.
Turning this into an answer...
Once a file is uploaded, have Lambda move it (using the Copy Object API), i.e. from uploads/123.png
to received/123.png
or something similar.
If a malicious user attempts to re-use the signed URL, it'll go to uploads/123.png
. Worst-case, Lambda checks it again and rejects the new file. Since your server's looking in received/
instead of uploads/
for files to process, we've rendered things safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With