Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S3 : Sending campain with private bucket file attachement fails because of incorrrect PresignedUrl #1499

Closed
julienvienne opened this issue Aug 31, 2023 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@julienvienne
Copy link

Version:

  • listmonk: [eg: v2.5.1]
  • OS: [ubuntu 22.04]

Description of the bug and steps to reproduce:

I try to use AWS S3 private bucket to save medias and send a new campain.
File upload is going well in my bucket using credentials, but when I try to send a new campain, listmonk creates a presigned URL to get the file back. This URL is not working in my case. I get a 403 error because :

<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>

The URL is build in this source code, but I cannot understand why the signature mismatch.
According to this StackOverflow post, it may be related to incorrect file path in the URL.

As a consequence, the campain stays indefinitively on the Running status

@knadh
Copy link
Owner

knadh commented Aug 31, 2023

Can you blur the sensitive details and share your S3 settings?

@julienvienne
Copy link
Author

Thank you for your concern. Here they are :
listmonk_settings

After few investigation, it seems that the generated link is fine in the media management dialog.
After uploading an image, it appears correcly in the dialog, and the image link is a presigned URL which is working fine.

list_monk_medias

However, sending the campain with this media goes to infinie running loop :
listmonk_fails_sending_attachment

In the logs dialog, I can read :

2023/09/04 13:47:27error processing campaign XXX : error fetching attachment 19 on campaign XXX: status code: 404 Not Found
2023/09/04 13:47:32error processing campaign XXX : error fetching attachment 19 on campaign XXX: status code: 404 Not Found
2023/09/04 13:47:37error processing campaign XXX: error fetching attachment 19 on campaign XXX: status code: 404 Not Found
...

@julienvienne
Copy link
Author

Hello @knadh,

I may found the bug here :
https://github.com/knadh/listmonk/blob/master/internal/media/providers/s3/s3.go#L108

It seems that ObjectKey: c.makeBucketPath(filepath.Base(url)) is used to get the S3 Object key from URL.
However, the presigned URL may contain additional data like X-Amz-Algorithm, X-Amz-SignedHeaders and others headers for AWS. As a result, the ObjectKey may not be correct.

I am not sure that the makeBucketPath(name string) cleans the header informations correctly.

@ashso
Copy link

ashso commented Sep 6, 2023

I'm encountering a problem similar to Julien's. I tried using Cloudflare R2, which is S3 compatible. I successfully uploaded a file to R2 and verified that I could fetch it from there. However, I'm seeing the same error in the log, but the link in the Media section seems to be incorrect as it's using a subdomain of s3.amazonaws.com. I've attached the configuration I used for reference.
image

p.s. I am also using the same version of listmonk, but run in a container

@julienvienne
Copy link
Author

To sum up :

  • the presigned URL is not the problem here (contrary to the issue title). It is working fine in the media dialog
  • the bug seems to come from the GetBlob(url string) , which is used to retrieve the file to create the campain attachment.
  • In this function, the s3 object key is determined from url in a way that may be incorrect.
  • as a result, the file is not found on s3 and we get 404 error

@knadh knadh self-assigned this Sep 7, 2023
@knadh knadh added the needs-investigation Potential bug. Needs investigation label Sep 7, 2023
@knadh knadh closed this as completed in 04e571d Sep 19, 2023
@knadh
Copy link
Owner

knadh commented Sep 19, 2023

Thanks for investigating and detailing this issue @julienvienne. Turns out, there were multiple issues here.

  • There's a silly bug with the default 14d expiry value. d is not a valid timestring suffix. This has to be specified in hours. 8f2a08b addresses this.
  • Discovered that S3 only supports a max of 7 days for presigned URLs. Anything above, it throws an error.
  • GetBlob() indeed had a bug, which 04e571d fixes.

@ashso you've to set the appropriate Cloudflare URL in the "custom public URL" field.

@knadh knadh added bug Something isn't working and removed needs-investigation Potential bug. Needs investigation labels Sep 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants