flysystem icon indicating copy to clipboard operation
flysystem copied to clipboard

S3 v3 createDirectory() is triggering a 403 Forbidden Client Error

Open rk opened this issue 10 months ago • 2 comments

Bug Report

Recently upgraded application with Laravel 10, Laravel Backpack 6, with barryvdh/elfinder as a filemanager for the client (for organization and bulk-uploads). Prior to these upgrades, the application had stable access to the S3 bucket and could easily create/delete/upload files and folders.

Q A
Flysystem Version 3.27.0
Adapter Name league/flysystem-aws-s3-v3
Adapter version 3.27.0
PHP 8.2

Summary

We recently upgraded an application to Laravel v10, Backpack v6, and the latest elfinder. Previous to these upgrades, for some unknown time, the application was able to call $adapter->createDirectory('test') and succeed.

Now, we get the following error.

elfinder debug: [error] [elfinder] Unable to write file at location: Brand Resources/test/.
Error executing "PutObject" on "https://[bucketname].s3.amazonaws.com/Brand%20Resources/test/"
AWS HTTP error: 
Client error: `PUT https://[bucketname].s3.amazonaws.com/Brand%20Resources/test/` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>T9W6QS (truncated...)
 AccessDenied (client): Access Denied - <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>T9W6QSBF8FVGBK4K</RequestId><HostId>FGsBhIy7PIIRYJ0UGNBeOQujDI8t6NSOpcGcDCcsaXCy7J6Lwton0dHSlSImGKkmsGmywvpJf5hfyZsQ/q/2tEt2qpLH/I8fLUdqGpZRHEY=</HostId></Error>

I updated the IAM policy to allow all S3 actions on the bucket for testing (I don't recommend this, but had to rule a policy issue out):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::bucketname",
                "arn:aws:s3:::bucketname/*"
            ]
        }
    ]
}

So this doesn't appear to be an issue with the IAM policy attached to the user. I can upload files to this same bucket/adapter, but it immediately dies upon a call to createDirectory().

Laravel configuration for the disk is 100% stock. Nothing custom.

Bucket settings/details:

  • Most feature flags are disabled.
  • Permissions: block all public access ON
  • Metrics: 4.1GB stored

How to reproduce

Reproducing this error does not require use of elFinder. So I can eliminate that as a cause of the issue.

Steps to reproduce for me:

$ php artisan tinker
Psy Shell v0.12.3 (PHP 8.2.18 — cli) by Justin Hileman
> \Storage::disk('s3')->createDirectory('test')

   League\Flysystem\UnableToWriteFile  Unable to write file at location: test/. Error executing "PutObject" on "https://[bucketname].s3.amazonaws.com/test/"; AWS HTTP error: Client error: `PUT https://[bucketname].s3.amazonaws.com/test/` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>FS62F3 (truncated...)
 AccessDenied (client): Access Denied - <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>FS62F37KJGX47BRS</RequestId><HostId>pR6z/0NhBPLqnFt5FTbmFI/VOkTidY2rF1kwXgysSqEzik8jF2NNJeewJkZb9dhC8QwGiByJOzk=</HostId></Error>.

> \Storage::disk('s3')->createDirectory('Brand Resources/test')

   League\Flysystem\UnableToWriteFile  Unable to write file at location: Brand Resources/test/. Error executing "PutObject" on "https://[bucketname].s3.amazonaws.com/Brand%20Resources/test/"; AWS HTTP error: cURL error 35: A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot. (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://[bucketname].s3.amazonaws.com/Brand%20Resources/test/.

The 2nd test is the first time I've observed that error. Is this server related?

rk avatar Apr 19 '24 19:04 rk

Hi, I'm not sure how a Flysystem change can cause a 403 in this case. I would have expected a 400. Are you able to do any other write? Since directory creation in S3 is just a relatively normal write. If you have a bucket that enforces no ACL, you may need to configure the default directory permissions to be private instead of the default public permissions.

frankdejonge avatar Apr 20 '24 11:04 frankdejonge

Hi Frank,

Yes, I can write files to both locations. I thought to check that, and I'm wondering if it's an AWS client library issue. I maintain several other projects with similar policies, and library versions, and they haven't had the issue.

The bucket is 100% private, and we use signed links for any downloads.

It's been driving me crazy this week.

rk avatar Apr 20 '24 21:04 rk