Closed seisvelas closed 3 years ago
Or, StackOverflow discussion that might be helpful: https://stackoverflow.com/questions/17533888/s3-access-control-allow-origin-header
Or if you're okay with me accessing S3, I can do it.
We allow only origins of known extensions. For example, on (prod) Firefox I can download the attachments ok.
Was this a local browser you were testing on? What was the extension id? I could add it to the S3 config.
(S3 will I think read the host header to respond with a CORS header if it's one of the good ones, else it will send back no cors header)
Ref: https://mail.google.com/mail/u/human@flowcrypt.com/#inbox/FMfcgxwKjKqwwMxfnWvjHwtsKfkHMhQc
My origin is moz-extension://7de1b3a0-9852-49de-ae57-8bef77b67cb7
I just removed and re-added the extension to Firefox and tried again - I get the same problem.
Now my origin is moz-extension://eb56e10a-70b2-4a2a-9bc8-662d1e890489
The prod Firefox is moz-extension://39553fca-76d4-4791-bf00-b4dfede6fd45
. Can you reproduce this on the prod?
I just installed fresh from the link on flowcrypt.com for Firefox, my origin is moz-extension://e0a5c2fc-950d-4492-8994-0dc5e0fcc885
and I'm getting this error.
Here is my request:
GET /attachment/d78d87f191052d54fa58eafb49efe22e07b9303e.pgp HTTP/1.1
Host: flowcrypt.s3.amazonaws.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Origin: moz-extension://e0a5c2fc-950d-4492-8994-0dc5e0fcc885
Connection: keep-alive
Range: bytes=34404-
If-Range: "8b4c7b5f81e3f156c1fd011e294f6a7b"
and the response:
HTTP/1.1 200 OK
x-amz-id-2: 2OCnBgxSr8YJwkuRg+bxwvRXQEp7lBzuRRECZGCEl291p6Z9CeuYqHjPnYv7we7Ka1VXgR3H8Lk=
x-amz-request-id: 167AC324FF4B1D2F
Date: Tue, 08 Dec 2020 00:19:03 GMT
Last-Modified: Mon, 07 Dec 2020 14:48:51 GMT
ETag: "8b4c7b5f81e3f156c1fd011e294f6a7b"
x-amz-server-side-encryption: AES256
Accept-Ranges: bytes
Content-Type: application/octet-stream
Content-Length: 226915
Server: AmazonS3
The error in my console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://flowcrypt.s3.amazonaws.com/attachment/d78d87f191052d54fa58eafb49efe22e07b9303e.pgp. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Something we could perhaps improve is the error message as displayed to the user: "Error downloading file - no internet.". When that error is going to occur, we could check to see if it's a CORS issue and adjust the error message accordingly.
For context, I'm trying to open the attachment in this support email: https://mail.google.com/mail/u/human@flowcrypt.com/#inbox/FMfcgxwKjnXXjhVxfZmwmqJsMLXmzRJB
Thank you for debugging this.
For example I can open that attachment just fine on Firefox:
I can see the origins are different. How come your origin is different from mine, if you just got it from Flowcrypt.com? Interesting. I'll try to re-download firefox in a separate profile.
I just re-downloaded it myself and have moz-extension://4ed7f644-c3b5-4bf1-983f-2c8718f52222
...
There surely is a mechanism to keep a stable extension id. Can you please take a look at what we have to do? We are using the addons.mozilla.com self-publish mechanism, where I'm having Mozilla sign each release, but then we are self-hosting a json file at https://flowcrypt.com/api/update/firefox the individual xpi fles.
There surely is a mechanism to keep a stable extension id.
Unfortunately, this appears not to be the case. Consider the following,
The internal UUID is deliberately created per installation of an extension, to avoid fingerprinting, you can see a longer discussion at https://bugzil.la/1372288
These IDs currently are unique per installation of an extension, but there is a discussion about this happening over at https://bugzilla.mozilla.org/show_bug.cgi?id=1271663 211
Since this extension ID in webextensions, is unique per user (https://bugzilla.mozilla.org/show_bug.cgi?id=1372288), it gives the possibility of fingerprinting the user on the server side based on the Origin header.
The Internal UUID displayed after moz-extension:// is particular to your Firefox.
Firefox's unfortunate approach to extension uuid assignment will probably be fixed eventually to work more like Chrome, based on discussions in the bug tracker, because it can be abused for tracking users by fingerprinting the unique origin header sent by their extension.
But that's not something we can wait on - the last comment from the dev in the bug tracker for this issue was 7 months ago saying they won't be fixing it soon.
I see, it's a feature. Interesting. What's your thoughts on allowing S3 CORS * security wise?
What's your thoughts on allowing S3 CORS * security wise?
I'm not a fan, but the URL's with encrypted profile attachments are publicly accessible anyway (as long as you know the URL). I don't think an attacker could do much with this, but I'm learning all I can about CORS vulnerabilities in case I'm missing something (PortSwigger Academy has very thorough CORS vulnerability labs that are helping a lot).
With our current setup, though, we can't set Access-Control-Allow-Origin: *
anyway, because browsers don't let you have both Access-Control-Allow-Origin: *
and Access-Control-Allow-Credentials: true
set simultaneously. The usual workaround is to just serve a CORS header that matches the Origin from the request (I'm sure AWS makes this easy to do, but if you need help I can set it up myself first on AWS free trial, then give you detailed instructions).
The GET request doesn't really need Access-Control-Allow-Credentials: true
anyway. So maybe we could set POST requests to only allow the origin flowcrypt.com
with Access-Control-Allow-Credentials: true
(from the backend), and the GET requests could allow all origins but omit Access-Control-Allow-Credentials.
Let me know if you want any guidance for doing all of this on AWS :) In the meantime I'm going to look into more CORS vulnerabilities. I really don't want to suggest you do something unless I understand it very well. But so far I think we should be totally fine.
Almost all CORS attacks rely on Access-Control-Allow-Credentials: true
, so if we could remove that for GET requests, allowing all origins for GET would be fine. And for POST, I think the only needed origin is flowcrypt.com, since that gets called from our backend. So that should solve any issue I can think of (but like I said, I'm still looking into all kinds of CORS attacks, so I'll update this late tonight after I study a ton and feel more confident
I think browser extension posts to S3 directly, after getting authorization form from backend
On Sat, 12 Dec 2020, 03:01 Alex Vazquez, notifications@github.com wrote:
Almost all CORS attacks rely on Access-Control-Allow-Credentials: true, so if we could remove that for GET requests, allowing all origins for GET would be fine. And for POST, I think the only needed origin is flowcrypt.com, since that gets called from our backend. So that should solve any issue I can think of (but like I said, I'm still looking into all kinds of CORS attacks, so I'll update this late tonight after I study a ton and feel more confident
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/FlowCrypt/flowcrypt-browser/issues/3026#issuecomment-743640053, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQDZENAF7LTNRUQOALACX3SULFIFANCNFSM4SRMLBQQ .
Discussion on Keybase:
onirony Sorry to message you about this here, but I am a bit confused. So, I was thinking of profile messages, which are uploaded from the backend But for normal attachments, they don't even need S3, right? So when does the extension upload to S3? tomjh try a password protected message with attachments, and see the network tab onirony It calls api/message/token to get the auth stuff, then api/message/upload to host it, but no POST to S3 for me tomjh Maybe this changed. I'll have to take a look
So for now we're waiting to look into if the browser really does post directly to S3 anywhere.
Indeed password-protected messages these days go from user to backend to S3.
Therefore POST is always from backend.
Therefore we could do Access-Control-Allow-Origin: *
on GET, and Access-Control-Allow-Origin: flowcrypt.com
on POST. Did it get it correctly?
Therefore we could do Access-Control-Allow-Origin: * on GET, and Access-Control-Allow-Origin: flowcrypt.com on POST. Did it get it correctly?
Yep, correct - we should be able to go ahead and make that change! Let me know when it's done and I'll test it on Firefox and (hopefully) close this issue.
Thanks for verifying that POSTs only come from the backend!
@tomholub I'm getting a new, different error when opening attachments sent via the encrypted contact page:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://flowcrypt.s3.amazonaws.com/attachment/2fe6179da6ed675fc0c21fe3416e0f5a801ffcbd.pgp. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Looking at the response, it appears the header is not being sent at all.
Here is the error from a user perspective, as always:
Did you change CORS settings? If so, I believe we may have inadvertently excluded CORS headers entirely on GET requests, rather than allowing all origins (which was our intent).
So there appear to be two separate bugs now.
In Firefox, as noted in my previous comment, CORS headers aren't received at all:
And on Chrome, the headers come in just fine but the preview fails for other reasons:
Here are the good headers, which are not the problem:
But here's the actual HTML for the image:
<div id="attachment-preview-container">
<img src="blob:chrome-extension://bnjglocicdkmhmoohhfkfkbbkejdhdgc/eafb680e-46a7-4a65-b5ed-b46f25ee2404" class="attachment-preview-img" alt="fc.jpeg">
</div>
So the img source is obviously bad. I'm not what's going on there. We must have broken how profile message attachments are decrypted and loaded into the preview blob, and since we probably don't have a test for that we didn't notice.
At least, that's my hypothesis, and if it's true we need to do two things:
updated on both test and prod S3 bucket
Steps to reproduce:
Result:
And if you check the console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://flowcrypt.s3.amazonaws.com/attachment/74b45d0f43841befe54e693d4e7dfb8ac2745a66.pgp. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
And indeed, the files on S3 really are served without any CORS header.
Here are some S3 docs about enabling CORS: https://docs.aws.amazon.com/AmazonS3/latest/user-guide/add-cors-configuration.html