An extension is probably not needed. JavaScript and local storage allow you to do this kind of stuff. Proton Drive and Mail accomplish this without an extension.
post
I think you can get away with using the web crypto apis and storing the private key in indexeddb. If you want users to be able to change devices or recover after blowing away their client storage, allow the user to download their private key and save it to a password manager.
IndexedDB is same-origin storage, readable by any script the origin serves. So the keys would not be safe from the host.
I mean no offense by this at all, but I wouldn’t because it would indicate a poor understanding of cryptography to me as a user. Either that or being intentionally misleading. In either case, probably unsafe for the user. There does not need to be an extension to encrypt content such that the server never has access to it. It can be encrypted and sent to the host with a key the server never possesses.
And how do you propose the web app provides the code to do that encryption without gaining access to the key?
It doesn’t. The code your site provides is downloaded by your client’s browser. It uses a key on their side that is never sent back to your server. Same as if you did it with an extension or application. This is well trodden ground, and used across the internet such that hosts have zero knowledge of their users’ data aside from in its encrypted state.
Actually, let me give a little ground here. There is a subtle but real benefit to an extension or signed application. With just JavaScript, a server could on a new page load deliver an altered code that would introduce a compromise. If that is the threat you want to mitigate for, you’re onto something. If you’re talking high stakes, and you make it clear this is the threat for which you’re protecting users, then I could be convinced.
The point is you can't prove the server won't serve you code that won't take your key and send it somewhere arbitrary.
You're saying you don't want users to have to trust the website code that the server offers. So why would the user trust the extension instead?
Maybe because you can't make sure the server uses the code it advertises without modification (The source code could be open and safe, but how can you make sure the website is actually using that?), while the extension is open source and could be downloaded directly from Github by the user. And if enough websites start using this system, it could gradually stop being an extra extension for that one website.
Maybe because you can’t make sure the server uses the code it advertises without modification
You'd have the server provide the code to your browser, and do the encryption/decryption client-side.
while the extension is open source and could be downloaded directly from Github by the user.
I would not install an arbitrary browser extension from Github. That's just bad security hygiene. Extensions have way too many privileges, there's not enough mechanisms to ensure that an extension is used only on the site that it's intended for, and there's no safe way to maintain updates. Heck, even extensions distributed on browser's official marketplaces have been shown to be ridden with malware.
If you're going to distribute code to run client-side for encryption/decryption, you may as well consider WASM. At least that's sandboxed...
You'd have the server provide the code to your browser, and do the encryption/decryption client-side.
Yes, OP has a problem with this part. You'd have to trust the website to serve you the clean client side JS each time you use it. The proposal requires you to check the source code (which is plain un-minified JS) of the extension to make sure it's doing what's advertised when you download it the first time and with each update, instead of having to check the client side (obfuscated / minified) JS of every website each time you use it.
I would not install an arbitrary browser extension from Github. That's just bad security hygiene. Extensions have way too many privileges, there's not enough mechanisms to ensure that an extension is used only on the site that it's intended for, and there's no safe way to maintain updates.
That's true, but auditing that one extension (even on every update), which may be used by other websites in the future, giving it more attention and audits, is a lot easier than checking the client side JS of every website.
is this asking too much from users?
Installing a browser extension for one site? From usability point of view, how is that any different than installing an app for each service/company?
I wouldn't, but obviously there seems to be many people who install an app for everything.
I wouldn't install a browser extension over an app. And I probably wouldn't install a browser extension for a web app.
I've read the thread. Your argument for an extension is to make it open source, why couldn't your front end code be open source instead?
The front end code could be open source, but you'd still have to trust the web server to actually serve you the same code.
If what you're building is worth the hassle of installing the add-on and viewing the content, I suppose. There's not many programs people use PRIMARILY for security. You wouldn't use a note program that has audited security if you can't save notes, for instance.
Can you derive the private key from the password? Like PBKDF2 or something. I guess it's what most E2E sites do. I wouldn't install anything unless it was for work and involved me receiving money.
Something along these lines is a good idea, but be aware you need extra considerations to keep the e2ee intact. If like most websites you would send the password to the server to login, and if you derive the private key from the password, suddenly the server would have your private key.
There's probably something you can do with hashing before sending to the server on login, but I don't have enough confidence to be definitive on that.
PBKDF2 is exactly what I'm using right now. The other reason for the extension is to prevent the host from ever having access to the key or the plaintext content. Sure, if you trust the host, the web code could be written to never send plaintext content back to the server. But I'm trying to eliminate that kind of trust requirement.
The user's going to have to trust your code one way or another. Making it a separately downloaded extension/application, rather than some js in the browser page, doesn't change that.
Making the client open source means its auditable by the public. Making a server open source doesn't mean anything because you don't know if the host you're talking to is actually running that code.
It's not the server code which is the question though, it's the client side, which either way is downloaded from somewhere you control (whether in minified js to run in the browser, or binary blob of a desktop app). A malicious developer can quite easily insert different code rather than the published source in either situation.
I guess if you have a traceable build pipeline which is entirely under control of a trusted cloud provider, that might do it.
But if so then there's no reason you can't make the web client "binary" available in the same way, as say a webroot zip or a container image. People can run it themselves against your backend api, or audit the frontend code your server is serving against the trusted version.
Or for the hell of it, write your web client with its encryption code in plain js rather than minifying it or using a framework. Then someone can view source on the web page and literally see the client source which is running.
Not the most maintainable solution of course, but highly transparent.
or audit the frontend code your server is serving against the trusted version.
OK but that requires everyone to be a vigilant user. It's much easier for users to just install the software themselves and verify the checksum matches.
Well I heard that safety is always a compromise between convenience and security. I think this would only make sense if you have a provider that you can trust now to provide a clean extension, but you can't trust to not do a rugpull or be forced by agents to suddenly implement a vulnerability. But that is basically specifically targeting you or your group. So this is already incredibly niche.
For most people, you either trust or you don't, and preferably you only trust a server in a neutral country like Switzerland. If you make it too complicated you diminish the usefulness of the service.
I believe it would be far more secure to have a native linux app written in e.g. rust to do all this. For an encrypted messenger for example.
What? Lol no. And a site like that probably shouldn't have signatures. Something like Bernstein authenticators would be way preferable.
In part that sounds like what zeronet did, but that was static p2p websites. User content was signed and distributed by the user. But the code of the website could block and filter the user content. Everything was handled by client-side javascript basically
No, as there's no use case for me.
Not all data that I share is sensitive. Server stored stuff, unencrypted is fine for me.
As for other sorts of sensitive stuff, Signal works perfectly fine for me.
Checkout cryptpad, it may inspire you ideas on how to implement an app to hold user-encrypted contents
On Cryptad's security page, they say:
some entities still need to be trusted in order to guarantee security: Your chosen CryptPad instance to run the same code as the one published on GitHub
This is the trust requirement I am trying to avoid by making the browser extension open source and independently verifiable.
If you want it to work, I think you'll need to start with a group of trusted contacts who run it because they know you and want to use what you've built.
If it really solves some problems, word will spread out from there.
If it's a solid extension which could be used by other websites, and it's explained clearly like in your post by the website which needs it, then probably yes.
Hell no. I don't install any extensions for any reason other than uBlock and a pw manager. Just because you say "trust me, bro" doesn't make your extension secure or privacy - focused.
Https already encrypts content during transit. Just use login/password/totp/passkey.
all 50 comments