1

I've heard a lot of people say that the Web Crypto API is not very safe. For example: https://tonyarcieri.com/whats-wrong-with-webcrypto, Problems with in Browser Crypto. However, I'm looking to use the Web Crypto API for a completely different purpose.

I want to create a static website (html, css and javascript files) on server run by myself which will allow me to open the website url, choose a file, and then encrypt the file with a password using PBKDF2 and AES-GCM.

Are there any security issues I would run into?

  • 2
    If the server is compromised by an attacker, then the attacker may be able to inject malicious scripting into your page. But, being that this all can be done using a static page, why host the page on a server at all? Instead, you can store the page locally, and simply point your browser to the local page. FYI, see https://github.com/meixler/web-browser-based-file-encryption-decryption for a similar project. – mti2935 Aug 23 '22 at 17:15
  • @mti2935 This may be how I end up doing it. Do you know if there will be any security issues with the Web Crypto API in this case? – asdf3.14159 Aug 23 '22 at 17:37
  • welcome- depending on your choice of browser and what you want to do with the data you may hit snags from the `file://` scheme - one easy solution is to serve the static page locally and then access it via `127.0.0.1`, eg. using `python -m http.server` - one prob with this approach is you may then not be able to launch HTTPS webrequests to other servers, so for a longer-term solution you will likely need a locally configured https server, eg https://gist.github.com/DannyHinshaw/a3ac5991d66a2fe6d97a569c6cdac534 – brynk Aug 27 '22 at 03:52

1 Answers1

5

This use of the WebCrypto API sounds secure, assuming:

  • Your server is secure and the files cannot be tampered with. This is the assumption you've provided, so I'll assume myself that you've sufficiently hardened your server.

  • Your TLS configuration is secure. If your server or client are vulnerable to any of the numerous attacks against TLS (such as downgrade attacks due to support of old versions), an attacker could perform a MITM attack and serve your browser with malicious JS.

  • Your network and its upstream are secure (or you pin your TLS certificate). Even if you use TLS, an attacker could provide you with a false DNS answer, sending you over to a malicious site run by them, even if you typed in the correct URL. Even if an attacker is not on your network, do you fully trust that your ISP is not vulnerable to DNS cache poisoning? If you pin the cert, then this issue is largely moot as your browser will refuse to load a malicious page.

  • Client-side side-channel attacks (including within the browser) are not an issue. It's not uncommon for serious side-channel attacks against browser-based cryptography to exist. In fact, this can sometimes even be exploited by one tab to steal secrets in another tab!

  • Your browser is secure and has not been compromised. While the server may be secure, your browser is another endpoint that is vulnerable to compromise. This can come in the form of anything from malicious extensions that you've installed to a completely-compromised OS.

  • You use the WebCrypto API correctly. You say you'll use AES-GCM and PBKDF2, but you still have to understand how to do this securely. If you re-use a nonce, GCM mode breaks down completely. A good cryptography library will handle that for you, but you should still be aware.

It is true though that browser-based cryptography has improved significantly over the years. It no longer needs to rely on entropy sources of questionable quality or hacked-together crypto libraries.

forest
  • 64,616
  • 20
  • 206
  • 257
  • Thanks! What is a good web cryptography library? – asdf3.14159 Aug 27 '22 at 03:44
  • @asdf3.14159 Maybe something like [opencrypto](https://github.com/safebash/opencrypto)? You can also use WebCrypto directly if you know what you're doing. It's not so low-level that you'll need to create HMAC out of a hash and build PBKDF2 on that (it has `deriveKey()` to do it all for you), but it's still easy to shoot yourself in the foot. – forest Aug 27 '22 at 03:49