You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ro...@apache.org on 2022/08/08 12:55:38 UTC

[couchdb] 01/01: Upgrade hash algorithm for cookie auth

This is an automated email from the ASF dual-hosted git repository.

ronny pushed a commit to branch fix-4119
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 54be9579069f85abfd7a9df04ffac5a363356943
Author: Ronny Berndt <ro...@apache.org>
AuthorDate: Mon Aug 8 14:55:21 2022 +0200

    Upgrade hash algorithm for cookie auth
---
 src/couch/src/couch_httpd_auth.erl | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/couch/src/couch_httpd_auth.erl b/src/couch/src/couch_httpd_auth.erl
index c74ca9bd8..0d2d565ee 100644
--- a/src/couch/src/couch_httpd_auth.erl
+++ b/src/couch/src/couch_httpd_auth.erl
@@ -277,10 +277,13 @@ cookie_authentication_handler(Req) ->
 cookie_authentication_handler(#httpd{mochi_req = MochiReq} = Req, AuthModule) ->
     case MochiReq:get_cookie_value("AuthSession") of
         undefined ->
+            couch_log:info("Undefined AuthSession...", []),
             Req;
         [] ->
+            couch_log:info("Empty AuthSession...", []),
             Req;
         Cookie ->
+            couch_log:info("Cookie send...", []),
             [User, TimeStr, HashStr] =
                 try
                     AuthSession = couch_util:decodeBase64Url(Cookie),
@@ -294,22 +297,34 @@ cookie_authentication_handler(#httpd{mochi_req = MochiReq} = Req, AuthModule) ->
                         Reason = <<"Malformed AuthSession cookie. Please clear your cookies.">>,
                         throw({bad_request, Reason})
                 end,
+            couch_log:info("User: ~p, TimeStr: ~p, HashStr: ~p", [User, TimeStr, HashStr]),
             % Verify expiry and hash
             CurrentTime = make_cookie_time(),
+            HashAlgorithms = get_config_hash_algorithms(),
             case chttpd_util:get_chttpd_auth_config("secret") of
                 undefined ->
+                    couch_log:info("undefined secret...", []),
                     couch_log:debug("cookie auth secret is not set", []),
                     Req;
                 SecretStr ->
+                    couch_log:info("defined secret...", []),
                     Secret = ?l2b(SecretStr),
                     case AuthModule:get_user_creds(Req, User) of
                         nil ->
+                            couch_log:info("undefined user creds...", []),
                             Req;
                         {ok, UserProps, _AuthCtx} ->
+                            couch_log:info("defined user creds...", []),
                             UserSalt = couch_util:get_value(<<"salt">>, UserProps, <<"">>),
                             FullSecret = <<Secret/binary, UserSalt/binary>>,
-                            ExpectedHash = couch_util:hmac(sha, FullSecret, User ++ ":" ++ TimeStr),
+                            ExpectedHash = couch_util:hmac(hd(HashAlgorithms), FullSecret, User ++ ":" ++ TimeStr),
+                            ExpectedHashes = lists:map(fun(Alg) -> couch_util:hmac(Alg, FullSecret, User ++ ":" ++ TimeStr) end, HashAlgorithms),
+                            VerifiedHashes = lists:map(fun(Hash) -> couch_passwords:verify(ExpectedHash, Hash) end, ExpectedHashes),
+                            couch_log:info("ExpectedHash:   ~p", [ExpectedHash]),
+                            couch_log:info("ExpectedHashes: ~p", [ExpectedHashes]),
+                            couch_log:info("VerifiedHashes: ~p", [VerifiedHashes]),
                             Hash = ?l2b(HashStr),
+                            couch_log:info("Hash: ~s", [HashStr]),
                             Timeout = chttpd_util:get_chttpd_auth_config_integer(
                                 "timeout", 600
                             ),
@@ -333,6 +348,7 @@ cookie_authentication_handler(#httpd{mochi_req = MochiReq} = Req, AuthModule) ->
                                                 auth = {FullSecret, TimeLeft < Timeout * 0.9}
                                             };
                                         _Else ->
+                                            couch_log:info("false pw: ~p", [Req]),
                                             Req
                                     end;
                                 _Else ->
@@ -367,7 +383,10 @@ cookie_auth_header(_Req, _Headers) ->
 
 cookie_auth_cookie(Req, User, Secret, TimeStamp) ->
     SessionData = User ++ ":" ++ erlang:integer_to_list(TimeStamp, 16),
+    [HashAlgorithm | _] = get_config_hash_algorithms(),
+    couch_log:info("Generating new cookie...", []),
     Hash = couch_util:hmac(sha, Secret, SessionData),
+
     mochiweb_cookies:cookie(
         "AuthSession",
         couch_util:encodeBase64Url(SessionData ++ ":" ++ ?b2l(Hash)),
@@ -695,3 +714,8 @@ authentication_warning(#httpd{mochi_req = Req}, User) ->
         "~p: Authentication failed for user ~s from ~s",
         [?MODULE, User, Peer]
     ).
+
+-spec get_config_hash_algorithms() -> list(atom()).
+get_config_hash_algorithms() ->
+    HashAlgorithmStr = string:to_lower(chttpd_util:get_chttpd_auth_config("hash_algorithms", "sha256, sha")),
+    lists:map(fun binary_to_atom/1,re:split(HashAlgorithmStr, "\\s*,\\s*", [trim, {return, binary}])).