Just had a quick chat with Chris Anderson on IRC. His thoughts were
as follows, my comments in square brackets:
1. Move the secret into the config file so that it can't be stolen.
[I originally put the secret into the design doc so that it could be
easily replicated around a cluster, but config file options will need
to be synchronised in a cluster anyway and the config file seems like
a better place for a secret.]
2. As all the passwords are salted on a per-user basis, it's not
really a problem if anyone can load the "users" view. [[I feel
uncomfortable with leaking any kind of password information, however
hard it is to crack, but it's probably good enough for now and it's
useful for applications to be able to access a user directory of some
kind.]]
3. Future work would involve caching the user view rows in an ets
table for performance.
So the main thing left to be done is moving the secret into a config
option, which shouldn't take too long. This along with point #2 above
would mean no need to restrict access to _design/_auth.
--
Jason Davies
www.jasondavies.com
On 27 May 2009, at 14:04, Jason Davies wrote:
Hi Adam,
Thanks for that!
1) You're right, _design/_auth isn't protected against unauthorised
reads at the moment. The "users" view would also need to be
restricted, I guess restricting reads of _design/_auth to the
"_admin" role or similar will have the side effect of also
restricting access to any views it contains. Is there anything else
I need to do here? Once we have reader lists, perhaps we could do
away with having a special auth design doc and allow the name
"_auth" to be configured in local.ini.
2) Ah yes, I forgot to mention that part! For simplicity roles are
indeed also assigned from the same "users" view i.e. it should
return {password_sha: ..., salt: ..., roles: [...]}. It would be
simple to use a separate "roles" view and I can see that having a
separate view would probably be better in terms of separating
concerns.
In the future I think it might be worth going a step further and
making the authorisation part completely pluggable, so that
"authorization_handler" can be specified in local.ini to specify a
function that takes a username and returns a list of roles so that
e.g. an LDAP handler could be used without needing to touch the
cookie or any other authentication handlers.
--
Jason Davies
www.jasondavies.com
On 27 May 2009, at 13:29, Adam Kocoloski wrote:
Hi Jason, I've been following these updates with interest. Nice
work! A few quick questions:
1) Is the _design/_auth document protected against unauthorized
reads? I didn't see anything to that effect.
2) You didn't mention anything about authorization (e.g. the roles
list) in your blog post, but it looks like the code is still
assigning user roles based on the output of the users view. What
are your thoughts on this? Some people might say that it would be
better to assign the roles in a separate document or view.
In a future optimization we might want to model this authentication
handler as a process so that it doesn't have to open the userdb and
_auth doc on every request. Cheers,
Adam
On May 27, 2009, at 7:05 AM, Jason Davies wrote:
Hi again,
On 4 May 2009, at 23:31, Jason Davies wrote:
On 29 Apr 2009, at 17:29, Jason Davies wrote:
I'm in the finishing stages of writing a cookie-based
authentication handler for CouchDB in Erlang. This is primarily
going to be useful for CouchApps (apps running purely in
CouchDB), but this also touches on a generic way to authenticate
users via a CouchDB database, which could be adopted by the
current default HTTP Basic auth handler.
I've put the code up here: http://github.com/jasondavies/couchdb/tree/master
[snip]
Still to do:
- Use some kind of challenge/response mechanism for logging in
via AJAX. At the moment the login handler just takes a
plaintext username/password combination sent via POST. I was
thinking of using SRP (http://en.wikipedia.org/wiki/Secure_remote_password_protocol
), however I believe this would require state to be stored on
the server, and maybe isn't appropriate for this.
I've now implemented SRP auth and it is working merrily. I'm in
discussions with SRP's inventor, Tom Wu, about a potentially
simpler protocol as SRP implemented in JavaScript is probably
overkill for unencrypted HTTP (it is vulnerable to MITM injection
attacks of the JavaScript code itself, whereas SRP would
otherwise protect against active attacks). It might be worth
supporting a simpler protocol sent over SSL too e.g. plaintext
credentials.
Any suggestions for a more appropriate authentication protocol
would be much appreciated.
I've now ripped out the SRP code as it was a) too slow for modular
exponentiation for n with greater than 256 bits and b) overkill
due to the client code itself being sent over the wire thus losing
SRP's resistance against active attacks. A potential higher-
performing replacement auth protocol is SCRAM but for now I've
just implemented simple plain-text form-based auth, which works
even for non-JavaScript clients. For extra security simply add SSL.
I've now put the code into its own branch here:
http://github.com/jasondavies/couchdb/tree/cookie-auth
A brief write-up here: http://www.jasondavies.com/blog/2009/05/27/secure-cookie-authentication-couchdb/
along with some thoughts on SRP (which is truly awesome and I
hope browsers all support TLS-SRP someday!).
A code review would be appreciated and then hopefully we can get
this into trunk so that CouchApps can use cookie-based auth out-of-
the-box.
Thanks,
--
Jason Davies
www.jasondavies.com