diff options
author | Ronny <ronny@apache.org> | 2022-07-18 19:01:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-18 19:01:30 +0200 |
commit | daff65d8c8772c637eb60365d6e672543163a740 (patch) | |
tree | 3d3cbdefc48f985d25228a0a7f39ca48de4a6b7d | |
parent | 7fb96d2652ebccad8479d9d29a02ce76cd6e853b (diff) | |
download | couchdb-daff65d8c8772c637eb60365d6e672543163a740.tar.gz |
Replace SHA-1 with SHA-256 for cookie authentication (#4094)
* Replace Sha-1 with Sha-256 for cookie authentication
* Fix proxyauth_test and remove it from skipping tests
-rw-r--r-- | src/couch/src/couch_httpd_auth.erl | 18 | ||||
-rw-r--r-- | test/elixir/test/config/skip.elixir | 4 | ||||
-rw-r--r-- | test/elixir/test/proxyauth_test.exs | 99 |
3 files changed, 43 insertions, 78 deletions
diff --git a/src/couch/src/couch_httpd_auth.erl b/src/couch/src/couch_httpd_auth.erl index 47096e120..4fa5d04df 100644 --- a/src/couch/src/couch_httpd_auth.erl +++ b/src/couch/src/couch_httpd_auth.erl @@ -153,14 +153,14 @@ null_authentication_handler(Req) -> % Headers name can be defined in local.ini. By default they are : % % * X-Auth-CouchDB-UserName : contain the username, (x_auth_username in -% couch_httpd_auth section) +% cttpd_auth section) % * X-Auth-CouchDB-Roles : contain the user roles, list of roles separated by a -% comma (x_auth_roles in couch_httpd_auth section) +% comma (x_auth_roles in chttpd_auth section) % * X-Auth-CouchDB-Token : token to authenticate the authorization (x_auth_token -% in couch_httpd_auth section). This token is an hmac-sha1 created from secret key +% in chttpd_auth section). This token is an hmac-sha256 created from secret key % and username. The secret key should be the same in the client and couchdb node. -% Secret key is the secret key in couch_httpd_auth section of ini. This token is optional -% if value of proxy_use_secret key in couch_httpd_auth section of ini isn't true. +% Secret key is the secret key in chttpd_auth section of ini. This token is optional +% if value of proxy_use_secret key in chttpd_auth section of ini isn't true. % proxy_authentication_handler(Req) -> case proxy_auth_user(Req) of @@ -202,7 +202,7 @@ proxy_auth_user(Req) -> Req#httpd{user_ctx = #user_ctx{name = ?l2b(UserName), roles = Roles}}; Secret -> ExpectedToken = couch_util:to_hex( - couch_util:hmac(sha, Secret, UserName) + couch_util:hmac(sha256, Secret, UserName) ), case header_value(Req, XHeaderToken) of Token when Token == ExpectedToken -> @@ -308,7 +308,9 @@ cookie_authentication_handler(#httpd{mochi_req = MochiReq} = Req, AuthModule) -> {ok, UserProps, _AuthCtx} -> UserSalt = couch_util:get_value(<<"salt">>, UserProps, <<"">>), FullSecret = <<Secret/binary, UserSalt/binary>>, - ExpectedHash = couch_util:hmac(sha, FullSecret, User ++ ":" ++ TimeStr), + ExpectedHash = couch_util:hmac( + sha256, FullSecret, User ++ ":" ++ TimeStr + ), Hash = ?l2b(HashStr), Timeout = chttpd_util:get_chttpd_auth_config_integer( "timeout", 600 @@ -367,7 +369,7 @@ cookie_auth_header(_Req, _Headers) -> cookie_auth_cookie(Req, User, Secret, TimeStamp) -> SessionData = User ++ ":" ++ erlang:integer_to_list(TimeStamp, 16), - Hash = couch_util:hmac(sha, Secret, SessionData), + Hash = couch_util:hmac(sha256, Secret, SessionData), mochiweb_cookies:cookie( "AuthSession", couch_util:encodeBase64Url(SessionData ++ ":" ++ ?b2l(Hash)), diff --git a/test/elixir/test/config/skip.elixir b/test/elixir/test/config/skip.elixir index bb27f13cd..7fbcacef7 100644 --- a/test/elixir/test/config/skip.elixir +++ b/test/elixir/test/config/skip.elixir @@ -2,10 +2,6 @@ "CookieAuthTest": [ "cookie auth" ], - "ProxyAuthTest": [ - "proxy auth with secret", - "proxy auth without secret" - ], "ReaderACLTest": [ "unrestricted db can be read" ], diff --git a/test/elixir/test/proxyauth_test.exs b/test/elixir/test/proxyauth_test.exs index 6bf21920b..6a4b58561 100644 --- a/test/elixir/test/proxyauth_test.exs +++ b/test/elixir/test/proxyauth_test.exs @@ -4,27 +4,7 @@ defmodule ProxyAuthTest do @moduletag :authentication @tag :with_db - test "proxy auth with secret", context do - db_name = context[:db_name] - - design_doc = %{ - _id: "_design/test", - language: "javascript", - shows: %{ - welcome: """ - function(doc,req) { - return "Welcome " + req.userCtx["name"]; - } - """, - role: """ - function(doc, req) { - return req.userCtx['roles'][0]; - } - """ - } - } - - {:ok, _} = create_doc(db_name, design_doc) + test "proxy auth with secret" do users_db_name = random_db_name() create_db(users_db_name) @@ -38,19 +18,19 @@ defmodule ProxyAuthTest do :value => users_db_name }, %{ - :section => "couch_httpd_auth", + :section => "chttpd_auth", :key => "proxy_use_secret", :value => "true" }, %{ - :section => "couch_httpd_auth", + :section => "chttpd_auth", :key => "secret", :value => secret } ] run_on_modified_server(server_config, fn -> - test_fun(db_name, users_db_name, secret) + test_fun(users_db_name, secret) end) delete_db(users_db_name) end @@ -62,16 +42,12 @@ defmodule ProxyAuthTest do |> Enum.join("") end - defp hex_hmac_sha1(secret, message) do - signature = case :erlang.system_info(:otp_release) do - '20' -> :crypto.hmac(:sha, secret, message) - '21' -> :crypto.hmac(:sha, secret, message) - _ -> :crypto.mac(:hmac, :sha, secret, message) - end + defp hex_hmac_sha256(secret, message) do + signature = :crypto.mac(:hmac, :sha256, secret, message) Base.encode16(signature, case: :lower) end - def test_fun(db_name, users_db_name, secret) do + def test_fun(users_db_name, secret) do user = prepare_user_doc(name: "couch@apache.org", password: "test") create_doc(users_db_name, user) @@ -85,38 +61,24 @@ defmodule ProxyAuthTest do headers = [ "X-Auth-CouchDB-UserName": "couch@apache.org", - "X-Auth-CouchDB-Roles": "test", - "X-Auth-CouchDB-Token": hex_hmac_sha1(secret, "couch@apache.org") + "X-Auth-CouchDB-Roles": "test_role", + "X-Auth-CouchDB-Token": hex_hmac_sha256(secret, "couch@apache.org") ] - resp = Couch.get("/#{db_name}/_design/test/_show/welcome", headers: headers) - assert resp.body == "Welcome couch@apache.org" - resp = Couch.get("/#{db_name}/_design/test/_show/role", headers: headers) - assert resp.body == "test" + resp2 = + Couch.get("/_session", + headers: headers + ) + + assert resp2.body["userCtx"]["name"] == "couch@apache.org" + assert resp2.body["userCtx"]["roles"] == ["test_role"] + assert resp2.body["info"]["authenticated"] == "proxy" + assert resp2.body["ok"] == true + end @tag :with_db - test "proxy auth without secret", context do - db_name = context[:db_name] - - design_doc = %{ - _id: "_design/test", - language: "javascript", - shows: %{ - welcome: """ - function(doc,req) { - return "Welcome " + req.userCtx["name"]; - } - """, - role: """ - function(doc, req) { - return req.userCtx['roles'][0]; - } - """ - } - } - - {:ok, _} = create_doc(db_name, design_doc) + test "proxy auth without secret" do users_db_name = random_db_name() create_db(users_db_name) @@ -128,20 +90,20 @@ defmodule ProxyAuthTest do :value => users_db_name }, %{ - :section => "couch_httpd_auth", + :section => "chttpd_auth", :key => "proxy_use_secret", :value => "false" } ] run_on_modified_server(server_config, fn -> - test_fun_no_secret(db_name, users_db_name) + test_fun_no_secret(users_db_name) end) delete_db(users_db_name) end - def test_fun_no_secret(db_name, users_db_name) do + def test_fun_no_secret(users_db_name) do user = prepare_user_doc(name: "couch@apache.org", password: "test") create_doc(users_db_name, user) @@ -155,13 +117,18 @@ defmodule ProxyAuthTest do headers = [ "X-Auth-CouchDB-UserName": "couch@apache.org", - "X-Auth-CouchDB-Roles": "test" + "X-Auth-CouchDB-Roles": "test_role_1,test_role_2" ] - resp = Couch.get("/#{db_name}/_design/test/_show/welcome", headers: headers) - assert resp.body == "Welcome couch@apache.org" + resp2 = + Couch.get("/_session", + headers: headers + ) + + assert resp2.body["userCtx"]["name"] == "couch@apache.org" + assert resp2.body["userCtx"]["roles"] == ["test_role_1", "test_role_2"] + assert resp2.body["info"]["authenticated"] == "proxy" + assert resp2.body["ok"] == true - resp = Couch.get("/#{db_name}/_design/test/_show/role", headers: headers) - assert resp.body == "test" end end |