Couchdb: Proxy Authentication doesn't work when proxy_use_secret=true

Created on 27 Feb 2018  路  12Comments  路  Source: apache/couchdb

Expected Behavior



When proxy_use_secret = true, I should be "authorized" with the correct password from X-Auth-CouchDB-Token header.

Current Behavior



"unauthorized" even I have the correct password from X-Auth-CouchDB-Token header.

Possible Solution



Add an example. Show how to use [proxy_user_secret] to this 2.1.1. doc
http://docs.couchdb.org/en/2.1.1/api/server/authn.html#proxy-authentication

Steps to Reproduce (for bugs)



  1. Having these in the config
    [couch_httpd_auth]
    require_valid_user = true
    secret = password
    x_auth_roles = X-Auth-CouchDB-Roles
    x_auth_username = X-Auth-CouchDB-UserName
    proxy_use_secret = true
    x_auth_token = password

[chttpd]
port = 5985
bind_address = 0.0.0.0
require_valid_user = false
authentication_handlers = {chttpd_auth, cookie_authentication_handler}, {couch_httpd_auth, proxy_authentication_handler}, {chttpd_auth, default_authentication_handler}

  1. Using this cURL command
    "AdminToDo" is the role name able to access my testing database.
    curl -X GET http://127.0.0.1:5985/my_testing_db?include_docs=true -H "Content-Type: application/json" -H "X-Auth-CouchDB-UserName: X-Auth-CouchDB-Username" -H "X-Auth-CouchDB-Roles: AdminToDo" -H "X-Auth-CouchDB-Token: password"

  2. I will get "error: unauthorized", seems the X-Auth-CouchDB-Token is not being used or doesn't know "secret = password" in the [couch_httpd_auth] section.

Context



I can't use proxy_user_secret=True even itis strongly recommended. When I have proxy_user_secret=false, using this header X-Auth-CouchDB-Roles works. It gets authorized; the wrong role will return unauthorized. It is what I expected.

Your Environment

  • Version used: 2.1.1.
  • Browser Name and version: Chrome Version 64.0.3282.140
  • Operating System and version (desktop or mobile): Windows 2008R2, IIS
  • Link to your project:
documentation

Most helpful comment

Just in case this is how you could create the token via command line using OpenSSL:

$ echo -n "username" | openssl sha1 -hmac "mysecret"
(stdin)= 7bdfca0f0926fe4255440da35417cd2dc79507e0

Then use it like:

curl "http://localhost:5984/_session" \
     -H 'X-Auth-CouchDB-Token: 7bdfca0f0926fe4255440da35417cd2dc79507e0' \
     -H 'X-Auth-CouchDB-UserName: username' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -H 'Accept: application/json'

All 12 comments

Correct, this functionality has not worked since the 2.0.0 release.

See #1174 for a proposal to revive it.

The workaround for now is to use very tight firewalling with your proxy server, only allowing it direct access to the CouchDB node(s).

I'm not sure whether to duplicate this ticket against #1174 or not, as I'm not 100% sure that ticket is proposing to fix this problem.

Just got bitten by this.

For a workaround, as @wohali suggested I'm running a small express-http-proxy on the same instance as couchdb which rejects request if they don't have the proper secret.

Isn't this working as expected? The only thing that's confusing is that you have to send the SHA-1 sum of the username using the secret instead of the secret directly:

In NodeJS this should give you the token:

crypto.createHmac('sha1', 'mysecret').update('username').digest('hex')

Then with curl you should get:

curl -X GET http://127.0.0.1:5984/_session -H "Content-Type: application/json" -H "X-Auth-CouchDB-UserName: username" -H "X-Auth-CouchDB-Roles: myadmin" -H "X-Auth-CouchDB-Token: "7bdfca0f0926fe4255440da35417cd2dc79507e0"
{"ok":true,"userCtx":{"name":"username","roles":["myadmin"]},"info":{"authentication_db":"_users","authentication_handlers":["cookie","proxy","default"],"authenticated":"proxy"}}

@fkaempfer Oh! My mistake. Is this in our test suite anywhere that you can find?

On first glance, no, I think there are no proxy tests.

This is not well documented, I found out about it by looking at the source here:

https://github.com/apache/couchdb/blob/master/src/couch/src/couch_httpd_auth.erl#L173

I think the hmac encoding of the username provides only slightly better security, but it is confusing to users. Perhaps the http auth should allow both options at the same time, either the secret directly (#1174), or the encoded username. If an attacker already knows about the secret, it is trivial to generate the tokens, so there is no harm in allowing the secret as a token, if users desire it.

I think the hmac encoding of the username provides only slightly better security, but it is confusing to users. Perhaps the http auth should allow both options at the same time, either the secret directly (#1174), or the encoded username. If an attacker already knows about the secret, it is trivial to generate the tokens, so there is no harm in allowing the secret as a token, if users desire it.

Benefit of encoding username is that it disallows malicious users from accessing others databases. If we were to allow directly supplying secret - specially when using it with a browser client like pouchdb.

If we were to allow both, at least we should document this point.

Sorry I'm a bit confused. The last comment says issue is fixed in apache/couchdb-documentation#291, but a review of that issue just shows a tiny bit of documentation to reference the token as being a SHA1 of the username using the secret as key.

But the issue (that authentication always fails if you try to use this feature) is not fixed at all. Issue #1174 has also been closed with no resolution that I could see.

So is there some secret fix that I've missed? Or is this broken functionality now intended? If so should all documentation relating to proxy auth with these headers be removed so people don't try to use them thinking they should work?

Finally, is the expected behaviour of proxy auth that you only need the couch username (and maybe roles?) to access Couch content without a password or hash or anything? This seems to be the current state since with "proxy_use_secret = true" I cannot auth, and without it I can auth with nothing but "X-Auth-CouchDB-UserName" and "X-Auth-CouchDB-Roles" and no other auth.

"The only thing that's confusing is that you have to send the SHA-1 sum of the username using the secret instead of the secret directly:"

If you want to propose a PR with a fix that restores things to the way they were in 1.x, be our guests :) Until then, we'll just document the current behaviour as how it's going to work for now, I'm afraid.

OK thanks, just checking I'm not missing something. Doesn't look like the secret is required at this point, only the username. I guess since in this setup Couch is only open to localhost requests proxied through another service the security doesn't need to be strong.

Just in case this is how you could create the token via command line using OpenSSL:

$ echo -n "username" | openssl sha1 -hmac "mysecret"
(stdin)= 7bdfca0f0926fe4255440da35417cd2dc79507e0

Then use it like:

curl "http://localhost:5984/_session" \
     -H 'X-Auth-CouchDB-Token: 7bdfca0f0926fe4255440da35417cd2dc79507e0' \
     -H 'X-Auth-CouchDB-UserName: username' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -H 'Accept: application/json'
Was this page helpful?
0 / 5 - 0 ratings