- 新しい順
- 投票が多い順
- コメントが多い順
Presumably each user will be uploading a photo to S3 with a unique prefix and name and also (presumably) you are keeping track of which prefix/name is being used by which user because you need that later. Admittedly this can be done with object metadata but it would be unwise to let the users set their own metadata - you can't (as you point out) trust what the user is doing.
If a presigned URLs was obtained by a malicious user then they can definitely upload an image that will appear to belong to the original user. The best defense here is a short expiry time on the URL. If a malicious user completely "owns" the browser that the target user is using then there isn't much you can do about that.
If a malicious user was to modify the front-end code to appear as another user (presumably to obtain a presigned URL from API Gateway) then the call to API Gateway should fail - because the call should be authenticated and the user identity (that has been modified) will not match the token that is sent to API Gateway. The whole idea of the tokens issued by Cognito is the end-user can't create a fake one.
If your code depends on a field that is controlled by the user in order to generate the persigned URL then I'd suggest that you need to change that so that the user identity is determined from something that the user cannot modify.
Thanks for your suggestions. I agree that ideally I would be able to pull the photo identification via the access token user ID; however, I'm not sure how to do this. My code logic is currently:
My concern is that a malicious user can simply log in as one user, obtain a presigned URL, and change the code so that it submits as another user ID in the metadata. I don't see at which step I can change it so that the uploaded file is automatically attributed to the user that is authenticated; my thinking is that it would have to be on the API Gateway/server side to prevent tampering.
Is there a better architecture instead of presigned URLs? Would it be better to instead have API Gateway use the presigned URL (instead of the frontend), and simply redirect the photo upload to this presigned URL via a Lambda? That way, API Gateway can handle metadata/user ID extraction. However, it would require routing large files from frontend to API Gateway to S3, which may hurt performance.
My thinking is that you should not allow the users to set metadata. In any particular security model, you can't trust things submitted to your application. Presumably you're doing some sort of post-processing on the upload to S3 (say, you're triggering a Lambda function). So, as you issue the presigned URL you also store (temporarily) the object prefix/name in a temporary place (I'd use DynamoDB) with the required metadata; then when the Lambda is triggered after upload it can retrieve the metadata and assign it to the object, deleting the DynamoDB record in the process. Extra work, yes.
(continued) but: More secure. As to uploading via API Gateway - you can definitely do this but be aware of the API Gateway and Lambda payload limits; the object can't be larger than 6MB due to the Lambda payload size. But if that works then you don't need presigned URLs at all.
Given the apparent complexity of your application I'd strongly recommend reaching out to your local AWS Solutions Architect and having a conversation about this.