There's a lot of discussion here about key exchange, and how you need to trust whatever service is managing the keys. From the demo, it looks like the key is basically a password. If you can share the password out-of-band through another secure channel (perhaps post it in a Signal chat or something), then your meeting should be secure. It can even be included as part of the link.
But then doesn't the Jitsi web server have to access password when you enter it on their website/have it in the link? Nope! It looks like they're putting the password in an anchor fragment in the URL, which is not sent to the web server [1]. So all encryption/decryption is being done client side (and is therefore real end-to-end encryption).
Yes, it's possible the web server is sending you evil JavaScript that is extracting your password anyway, but at least that's something you can in principle check. For all end-to-end encryption to work, you have to know your client is not compromised.
This goes straight to one of the biggest holes in the web platform: there is no mechanism for code signing or release tracking.
The web already has the world's most widely used public key infrastructure. When I go to amazon.com, I can be confident that my browser is talking to a service operated by Amazon, with nobody spying on or modifying messages in flight.
However, I have zero guarantees regarding the HTML/CSS/JS that service returns. It can return code modified for me specifically, different from what any other user of that app is running. For traditional server side rendered web apps, this is normal and expected. SPAs often return identical app resources for every user, and all user specific data is later transmitted via API calls... but nothing in the web enforces this.
For decentralized or end-to-end encrypted apps, this is very bad. Most Ethereum apps today, for example, are used primarily via Metamask browser extension. Nothing stops an operator of such an app from just serving a different, malicious version to one specific user, based eg on IP. Such a compromise would be very hard to prove.
Similarly, Jitsi might like to give users confidence that they are running the same code as everyone else, and that the code is logged, versioned, and open to security analysis.
In principle, an approach similar to Certificate Transparency could provide this kind of assurance.
For this to really work well, they would also have to practice good dependency hygiene and ship unminified bundles.
--
This is an important web primitive that's currently missing. Do any browsers have a solution somewhere in the pipeline?
For code signing to work you need to trust whoever is signing the code. As you mentioned, with HTTPS, all the contents are already signed by the web server. If Jitsi published a native app and signed it, would that even help you? You still have to trust them because they could have signed anything.
Maybe you mean to compare it to a copy that has already been audited by someone else? Then you might as well use the auditor's web server to get the client (and you can do this because Jitsi can be self-hosted). So I think it just comes down to connecting to web servers run by people you trust, since HTTPS already takes care of integrity checking.
If you are running a project like Tor Browser, that needs the highest security going, you would want:
1. Signing with an offline key, so an attacker can't make a release just by hacking the web server, and the key doesn't end up on however many hundred CDN web servers around the world.
2. Clear boundaries between releases, and a slow enough release schedule that third-party auditors can keep up.
3. Non-repudiation, so users know everyone else saw the same version they saw.
4. Reproducible builds from code in a public repo, so third-party auditors know what was released is what they reviewed.
5. An update process that verifies 1-3 before applying an update.
These requirements are fundamentally incompatible with webapps - where a no-questions-asked software update is only a press of F5 away, by design.
> These requirements are fundamentally incompatible with webapps - where a no-questions-asked software update is only a press of F5 away, by design.
If by "webapps" you mean "applications that run inside a web browser" then I disagree, since it is possible to pin a specific (presumably third-party audited) version of a webapp by using a static local bookmarklet or saved file. See my other comment [1].
You're right, though, that this is not the typical user experience for a web app, and you might reasonably believe that all webapps should be visibly associated with a domain on the internet.
Personally I think it is acceptable if a high security webapp requires a slightly less convenient UX compared to normal webapps. Nevertheless, it should still be quicker and safer to "install" a bookmarklet than install a native application like the Tor Browser.
If you talk HTTPS to a given host, assuming that TLS has not been compromised and the host itself has not been compromised, you can trust the app published by the developer to be correct. For stuff which is pulled in from other hosts which you don't control (e.g. CDNs), you can use subresource integrity: https://developer.mozilla.org/en-US/docs/Web/Security/Subres....
Agreed that it feels like there should be another mechanism to publish subresource integrity hashes for your own resources somewhere so that people can spot if your server or TLS gets compromised though (similar to CT). Sounds like someone else had the same idea at https://lists.w3.org/Archives/Public/public-webappsec/2014Ju... - I wonder why it didn't go anywhere?
Meanwhile, if you don't want to trust TLS or the host which originates the code, then for now you're probably better off using a desktop app (e.g. electron, although that comes with a whole different attack surface) or a browser extension which can be distributed as signed code.
It makes sense to use SRI to control the subresources which get loaded, but there is a clever trick which can be done to ensure that an entire webapp uses a fixed bundle of code.
The trick was discussed on Hacker News some time ago[1], but the basic idea is to use a bookmarklet (or saved local page) which contains a single <script> tag with an integrity hash baked into it. The loaded script (once the hash check passes) then acts as a bootloader for all the other resources that it pulls in, eval'ing them only if their hashes (or perhaps signatures) match a hardcoded list (or public key).
Of course there are some UX issues with this, such as the location bar not containing an actual domain (and reassuring padlock), although it might be possible to fix this depending on how the proposed <portal> tag[2] interacts with SRI. Also, the process of creating the bookmarklet is more awkward than just clicking a link, and it may have to be repeated every time a new version of the webapp is released (or rather, when the new version has been audited by one or more trusted entities).
With appcache / service workers and indexeddb you could probably build a tiny auditable offline loader, and then have it “install” payloads of which you can first verify signatures or audit the code. The main question remains why though.
Unfortunately it relied on the HPKP Suicide technique, since otherwise a compromised server could send a malicious update to the service worker code. Now that HPKP has been abandoned by browsers, WebSign is no longer viable (and it always required you to trust that the server really was throwing away its private keys).
As for the question of "why", it seems like you are asking either "Why would someone choose to write/use a webapp when they could just write/use a native app instead?" or "Why would a webapp developer/user care about the threat model of a web host being compromised?". Both of those questions have reasonable answers for at least some non-zero number of webapps.
Actually WebSign is still in production at Cyph, and never strictly depended on HPKP, with the caveats that:
1. Rather than simply prevent an attack, it shows a scary warning that compromised code will be run on the next reload, and
2. It relies on things that aren't intended as security features, and so is inherently more fragile than it was originally. In particular, if an attacker could fill up enough of a user's disk space, some browsers may just evict the WebSign instance.
We recommend that regular users of Cyph install the desktop and mobile apps, but it's at least a reasonably safe solution that significantly improves usability.
With appcache and a long lived expiration header on the manifest it would be possible to guarantee that no updates to the original loader are ever downloaded, hence no risk of server compromise. Regrettably appcache is deprecated.
yup, if you trust people to pass the URL around securely with a secret in a fragment, and you trust the recipients to keep the URL secret, and you're okay for anyone who ever discovers that secret to be able to decrypt and replay recordings of your conferences... then that may be acceptable.
Otherwise, you'll want a way to ensure that only devices belonging to users you've explicitly invited are able to participate (and you'll want to keep the secret evolving for forward secrecy, as amusing as it'd be for you to invite your sysadmin to a conference, only for him to go and decrypt the conversation prior to him joining to find out what you were saying before he came in...) - and this require key management to track who's who and who's trusted.
But then doesn't the Jitsi web server have to access password when you enter it on their website/have it in the link? Nope! It looks like they're putting the password in an anchor fragment in the URL, which is not sent to the web server [1]. So all encryption/decryption is being done client side (and is therefore real end-to-end encryption).
Yes, it's possible the web server is sending you evil JavaScript that is extracting your password anyway, but at least that's something you can in principle check. For all end-to-end encryption to work, you have to know your client is not compromised.
[1] https://stackoverflow.com/a/3081862