humanmade / S3-Uploads

The WordPress Plugin to Store Uploads on Amazon S3
1.93k stars 388 forks source link

wp s3-uploads verify False Positive #301

Open mattpramschufer opened 5 years ago

mattpramschufer commented 5 years ago

Plugin 'S3-Uploads' activated.
Success: Activated 1 of 1 plugins.
bash-4.2$ wp s3-uploads verify
Attempting to upload file s3://assets.***.com/uploads/1987710637.jpg
PHP Warning:  Error executing "PutObject" on "https://s3.us-east-2.amazonaws.com/assets.***.com/uploads/1987710637.jpg"; AWS HTTP error: Client error: `PUT https://s3.us-east-2.amazonaws.com/assets.**.com/uploads/1987710637.jpg` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>B7C133 (truncated...)
 AccessDenied (client): Access Denied - <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>B7C133F0810E4394</RequestId><HostId>E20UHUxCBFVceEVKUB23xehxfOYcWf/wvaXuvBLWGMxFrOWtImJBp/VMFMnxh6H/jD572tbQ8OE=</HostId></Error> in /var/www/lpm.**.io/wp-content/plugins/S3-Uploads/inc/class-s3-uploads-stream-wrapper.php on line 835
Warning: Error executing "PutObject" on "https://s3.us-east-2.amazonaws.com/assets.**.com/uploads/1987710637.jpg"; AWS HTTP error: Client error: `PUT https://s3.us-east-2.amazonaws.com/assets.***.com/uploads/1987710637.jpg` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>B7C133 (truncated...)
 AccessDenied (client): Access Denied - <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>B7C133F0810E4394</RequestId><HostId>E20UHUxCBFVceEVKUB23xehxfOYcWf/wvaXuvBLWGMxFrOWtImJBp/VMFMnxh6H/jD572tbQ8OE=</HostId></Error> in /var/www/lpm.**.io/wp-content/plugins/S3-Uploads/inc/class-s3-uploads-stream-wrapper.php on line 835
File uploaded to S3 successfully.
Attempting to delete file. s3://assets.**.com/uploads/1987710637.jpg
File deleted from S3 successfully.
Success: Looks like your configuration is correct.
bash-4.2$ ```
bradydowling commented 4 years ago

@mattpramschufer did you ever find a solution for this? I'm getting this same thing.

mattpramschufer commented 4 years ago

No I did not, I actually stopped using this plugin and switched to MediaCloud https://wordpress.org/plugins/ilab-media-tools/

It works fantastic, support is 100%, even has a migration tool to migrate from this plugin. Would 110% recommend.

bradydowling commented 4 years ago

Thanks for the recommendation. I'll probably just end up manually uploading my images to S3, we'll see though. For others that come upon this, note also that I am getting the same error even when I use AWS admin credentials.

kjrose commented 4 years ago

Ok, I had this exact issue and did some code debugging. It ended up being a ACL issue on the S3 bucket. The stream was failing to upload, not because the user (or admin) didn't have permissions, but because the ACL was setting to public-read and I had accidentally set the bucket to never allow public-read.

Once I realized this, I was able to resolve by adjusting the public settings to the following: image

lightningspirit commented 4 years ago

I can confirm this seems to be the issue. The bucket should NOT have "block public access" permissions set. Once this is set, it fixes the verbose output.

whyrg commented 3 years ago

The bucket should NOT have "block public access" permissions set

This is poor security practice. Instead, set define( 'S3_UPLOADS_OBJECT_ACL', 'private' ); in wp-config.php.

Doing so does mean you also intended to close off public S3 access, and probably being front-ended by CloudFront.

The original false positive on "verify" is still a bug though, since a failed operation should not result in "success".

lightningspirit commented 3 years ago

The bucket should NOT have "block public access" permissions set

This is poor security practice. Instead, set define( 'S3_UPLOADS_OBJECT_ACL', 'private' ); in wp-config.php.

AFAIK, that depends on the purpose of your S3 bucket, it's not a security issue per se.

However, I agree with following the least privilege principle and having the option to tell the ACL is a better way to configure it. In my case, all my S3 buckets are private by default and are proxied by Cloudfront, which is a great way to speed up delivery and save some bandwidth (and money).

So, my suggestion is to follow @whyrg comment. Proxy your S3 bucket using Cloudfront or any other CDN provider (you'll need to generate the right bucket policy), make it private by default and use define( 'S3_UPLOADS_OBJECT_ACL', 'private' ); in wp-config.php.