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

Uploading files to shared folders cause an "undecrypted file" to appear #213

Open
qgustavor opened this issue Sep 7, 2024 · 5 comments
Open

Comments

@qgustavor
Copy link
Owner

Describe the bug
If you share a folder then upload a file to it, when opening the folder it will show an "undecrypted file" like below:

image

To Reproduce

Create the folder and share it beforehand. For some reason using .link() isn't working and is failing with the following error:
Uncaught Error: EAGAIN (-3): A temporary congestion or server malfunction prevented your request from being processed. No data was altered. Retried 4 times.. But you can share using the official webclient.

import { Storage } from 'megajs'
const storage = await new Storage({ ... }).ready

const folder = storage.navigate('folder')
await folder.upload('new file.txt', 'contents').compete

Then open the shared folder and it will show an "undecrypted file".

Expected behavior

The file should appear normally in the folder.

Additional context

I guess something handling shared keys isn't working properly.

@qgustavor
Copy link
Owner Author

qgustavor commented Sep 7, 2024

Maybe that happens only if you upload a new file revision, which is what I'm trying to implement. No, I uploaded a new file and it happened again.

@qgustavor
Copy link
Owner Author

Seems the API for sharing folders changed: the "s2" method, when ran in the official web client, returns "AAAAAAAAAAAAAAAAAAAAAA" for "ha" and "ok". "ha" is just an authentication "digest" so clients can know the share was created by someone holding the storage key and "ok" is the folder share key encrypted with the storage key. While the client can work without "ha" by just disabling the check, they can't work without "ok", without it the client cannot access the folder share key. So it implies that this key is not being stored elsewhere, which is the cause for the "undecrypted file" to appear. Folders shared using the old method still works with MEGAJS, but folders shared with the new method have this issue. Also, seems like the server doesn't accept clients to share folders using the old method.

@qgustavor
Copy link
Owner Author

qgustavor commented Sep 8, 2024

It was changed two years ago in this commit. Looks like, after two years, they are enforcing those changes in the API servers. This commit alone adds A TON of new crypto code, some using Ed25519, some using RSA, probably for user to user folder encryption.

From developer tools alone, I don't know where the share folder could be stored now, the client does a "l" request along the "s2" request which includes a "i" parameter (which is also present on the "s2" request) and the folder handler. I guess this "i" parameter might denote where to find this key, as this request is created here. The server is called here in the code, so the i parameter is generated somewhere in between, my guess being on mega.keyMgr.sendShareKeys.

Then I notice that, slightly after sharing the folder, the client is calling upv with the same i as before and a ^!keys. Looks like that's a method to store attributes, so general data, in this case, the shared keys. I guess they changed folder sharing to use a more generic storage to store the shared keys, instead of a specialized storage which had to include that messy authentication scheme. It uses AES_GCM_12_16, which is authenticated so it avoids having to use a custom authentication scheme. Weirdly, that function is deprecated.

Most developer tools nowadays offer a stack trace of requests, but because MEGA's code use a call queue, this stack trace only shows when the code handles the queue, not which function added the request to the queue. Again, the extensive use of abbreviations is also a problem. I guess MEGA doesn't want users to ever review their code, as they make their code way too unreadable for anyone to understand. If they really tried to save bytes of traffic, they should have used Protocol Buffers instead of using single letter JSON keys and strings and have a way more maintainable code.

Anyway, back to research, I could not find where i is set. I guess I will have to get some help. Sadly, it completely breaks folder sharing in this library, probably one of the features I mostly used in this library. I wonder if it breaks custom folder sharing keys, I hope not.

@qgustavor
Copy link
Owner Author

In hindsight I guess we can write a wrapper for MEGA's API similar to what it could work if they used Protocol Buffers so the library itself is more maintainable. Like, instead of calling a: 'p' and a: 'u', the methods call messages and those messages translate those calls to the API format, and translate those results back into a more human-maintainable output.

It will increase the code size, sure, but code size is something to take care with those MEGA v2 improvements to tree shaking. Something I want from this library is to it being easy to read and understand, more people can read the code and check if it's safe as intended (unlike original MEGA's code). I know the current code needs to improve a lot (because #206), but that's a target to aim on.

@qgustavor
Copy link
Owner Author

There is a folder which I have for a long time that, when uploading a file with MEGAJS, it works fine, but when uploading with the official web client causes the "undecrypted file" to appear. I guess key management inside MEGA is not going well even for the official clients.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant