Avoiding Cloudant's HTTP Siren's Call

I was browsing Cloudant questions on Stackoverflow last night and came across a question about how to securely access Cloudant from directly from a browser. Summarising:

How do I securely pass my database credentials to the browser without the user being able to see them?

Over my time at Cloudant I've been asked variants of this questions many times. It makes me think that Cloudant and CouchDB's HTTP interface is a bit of a siren's call, luring unwary travellers onto security rocks.

Let's cut to the chase: sending credentials to an untrusted device means you have to assume those credentials are compromised. By compromised I mean that in any reasonable security model you have to assume the credentials are public and anyone can use them. Your data is available to anyone.

The above question also misses the point that it's not just the user themselves that must be unable to see the credentials, but everything else:

  • Their browser may have malicious addons sending passwords to an attacker.
  • Their laptop may have malware, sending passwords to an attacker.
  • Their home network may have other compromised machines or routers, sending pass--- you get the point.
  • And so on.

Everything that ever sees the credentials is able to leak them to the world. The actual person using the application is just one part of that (albeit one that's easier to phish). The only way to prevent this is to never allow the credentials to leave an environment controlled by you, the web application developer.

Over time, I've come to the conclusion that both Cloudant and CouchDB are best suited to being used like any other database, using a three-tier architecture. No one would consider having a browser connect to a Postgres database or SQL Server -- hopefully because it seems weird rather than just because it'd be difficult. Cloudant's HTTP interface makes it simple to connect from a browser, which can be misleading.

The HTTP interface was originally intended to enable couchapps, and can work well if you can live within the very tight constraints required in order to do this securely. This makes expressing many to most applications as CouchApps impossible. In addition, web application frameworks do a lot of work on your behalf to make your applications secure from a wide variety of attacks. CouchDB provides little help in this regard, which makes creating a secure application practically difficult even if it's theoretically possible.

For most applications, therefore, the temptation to directly connect from the browser should be avoided. It's only suitable for a pretty small subset of applications and then is hard to do securely when compared with a traditional architecture with an application in front of the database.

This of course isn't to say CouchDB's HTTP interface isn't secure. It's very secure when accessed over HTTPS; at least as much as any other database. Possibly more so, given the wide real world testing of the security properties of HTTPS. However, the security of a protocol is only as useful when its secrets are protected, and sending credentials to any device you don't control is almost certain to undermine this.