couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rnew...@apache.org
Subject couchdb commit: updated refs/heads/2221-bug-validate-auth-params to dbe769c
Date Sun, 06 Apr 2014 21:10:16 GMT
Repository: couchdb
Updated Branches:
  refs/heads/2221-bug-validate-auth-params 181a32c15 -> dbe769c60 (forced update)


Verify that auth-related properties are well-formed

Passing unexpected values to auth fields can result in server
issues. Notably, setting "iterations" to a string will cause an
infinite loop as the comparison 'when Iteration > Iterations' will
never evaluate to true.

The latest validate_doc_update prevents user docs with this problem
and administrators can deploy that check themselves (and only
administrators can edit design documents).

A server administrator can also insist on lower and upper bounds for
iteration count to reject weakly protected passwords and
resource-hungry passwords respectively.

COUCHDB-2221


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/dbe769c6
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/dbe769c6
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/dbe769c6

Branch: refs/heads/2221-bug-validate-auth-params
Commit: dbe769c604e5f1e000594336f8c4546bf9e3fd5a
Parents: 9f6a919
Author: Robert Newson <rnewson@apache.org>
Authored: Sun Apr 6 18:31:15 2014 +0100
Committer: Robert Newson <rnewson@apache.org>
Committed: Sun Apr 6 22:09:54 2014 +0100

----------------------------------------------------------------------
 etc/couchdb/default.ini.tpl.in   |  2 ++
 share/doc/src/config/auth.rst    | 24 ++++++++++++++++++++++++
 src/couchdb/couch_httpd_auth.erl | 17 +++++++++++++++++
 src/couchdb/couch_passwords.erl  | 15 +++++++++++----
 4 files changed, 54 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/dbe769c6/etc/couchdb/default.ini.tpl.in
----------------------------------------------------------------------
diff --git a/etc/couchdb/default.ini.tpl.in b/etc/couchdb/default.ini.tpl.in
index a0dd7db..934c6cd 100644
--- a/etc/couchdb/default.ini.tpl.in
+++ b/etc/couchdb/default.ini.tpl.in
@@ -72,6 +72,8 @@ timeout = 600 ; number of seconds before automatic logout
 auth_cache_size = 50 ; size is number of cache entries
 allow_persistent_cookies = false ; set to true to allow persistent cookies
 iterations = 10 ; iterations for password hashing
+; min_iterations = 1
+; max_iterations = 1000000000
 ; comma-separated list of public fields, 404 if empty
 ; public_fields =
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/dbe769c6/share/doc/src/config/auth.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/config/auth.rst b/share/doc/src/config/auth.rst
index 4127288..8311140 100644
--- a/share/doc/src/config/auth.rst
+++ b/share/doc/src/config/auth.rst
@@ -166,6 +166,30 @@ Authentication Configuration
       [couch_httpd_auth]
       iterations = 10000
 
+  .. config:option:: min_iterations :: Minimum PBKDF2 iterations count
+
+    .. versionadded:: 1.6
+
+    The minimum number of iterations allowed for passwords hashed by
+    the PBKDF2 algorithm. Any user with fewer iterations is forbidden.
+
+    ::
+
+      [couch_httpd_auth]
+      min_iterations = 100
+
+  .. config:option:: max_iterations :: Maximum PBKDF2 iterations count
+
+    .. versionadded:: 1.6
+
+    The maximum number of iterations allowed for passwords hashed by
+    the PBKDF2 algorithm. Any user with greater iterations is forbidden.
+
+    ::
+
+      [couch_httpd_auth]
+      max_iterations = 100000
+
 
   .. config:option:: proxy_use_secret :: Force proxy auth use secret token
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/dbe769c6/src/couchdb/couch_httpd_auth.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_auth.erl b/src/couchdb/couch_httpd_auth.erl
index 08841fb..6888f06 100644
--- a/src/couchdb/couch_httpd_auth.erl
+++ b/src/couchdb/couch_httpd_auth.erl
@@ -368,11 +368,28 @@ authenticate(Pass, UserProps) ->
             couch_util:get_value(<<"password_sha">>, UserProps, nil)};
         <<"pbkdf2">> ->
             Iterations = couch_util:get_value(<<"iterations">>, UserProps, 10000),
+            verify_iterations(Iterations),
             {couch_passwords:pbkdf2(Pass, UserSalt, Iterations),
              couch_util:get_value(<<"derived_key">>, UserProps, nil)}
     end,
     couch_passwords:verify(PasswordHash, ExpectedHash).
 
+verify_iterations(Iterations) when is_integer(Iterations) ->
+    Min = list_to_integer(couch_config:get("couch_httpd_auth", "min_iterations", "1")),
+    Max = list_to_integer(couch_config:get("couch_httpd_auth", "max_iterations", "1000000000")),
+    case Iterations < Min of
+        true ->
+            throw({forbidden, <<"Iteration count is too low for this server">>});
+        false ->
+            ok
+    end,
+    case Iterations > Max of
+        true ->
+            throw({forbidden, <<"Iteration count is too high for this server">>});
+        false ->
+            ok
+    end.
+
 auth_name(String) when is_list(String) ->
     [_,_,_,_,_,Name|_] = re:split(String, "[\\W_]", [{return, list}]),
     ?l2b(Name).

http://git-wip-us.apache.org/repos/asf/couchdb/blob/dbe769c6/src/couchdb/couch_passwords.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_passwords.erl b/src/couchdb/couch_passwords.erl
index d9e6836..bbf6d9a 100644
--- a/src/couchdb/couch_passwords.erl
+++ b/src/couchdb/couch_passwords.erl
@@ -22,12 +22,12 @@
 
 %% legacy scheme, not used for new passwords.
 -spec simple(binary(), binary()) -> binary().
-simple(Password, Salt) ->
+simple(Password, Salt) when is_binary(Password), is_binary(Salt) ->
     ?l2b(couch_util:to_hex(crypto:sha(<<Password/binary, Salt/binary>>))).
 
 %% CouchDB utility functions
 -spec hash_admin_password(binary()) -> binary().
-hash_admin_password(ClearPassword) ->
+hash_admin_password(ClearPassword) when is_binary(ClearPassword) ->
     Iterations = couch_config:get("couch_httpd_auth", "iterations", "10000"),
     Salt = couch_uuids:random(),
     DerivedKey = couch_passwords:pbkdf2(couch_util:to_binary(ClearPassword),
@@ -50,7 +50,10 @@ get_unhashed_admins() ->
 
 %% Current scheme, much stronger.
 -spec pbkdf2(binary(), binary(), integer()) -> binary().
-pbkdf2(Password, Salt, Iterations) ->
+pbkdf2(Password, Salt, Iterations) when is_binary(Password),
+                                        is_binary(Salt),
+                                        is_integer(Iterations),
+                                        Iterations > 0 ->
     {ok, Result} = pbkdf2(Password, Salt, Iterations, ?SHA1_OUTPUT_LENGTH),
     Result.
 
@@ -59,7 +62,11 @@ pbkdf2(Password, Salt, Iterations) ->
 pbkdf2(_Password, _Salt, _Iterations, DerivedLength)
     when DerivedLength > ?MAX_DERIVED_KEY_LENGTH ->
     {error, derived_key_too_long};
-pbkdf2(Password, Salt, Iterations, DerivedLength) ->
+pbkdf2(Password, Salt, Iterations, DerivedLength) when is_binary(Password),
+                                                       is_binary(Salt),
+                                                       is_integer(Iterations),
+                                                       Iterations > 0,
+                                                       is_integer(DerivedLength) ->
     L = ceiling(DerivedLength / ?SHA1_OUTPUT_LENGTH),
     <<Bin:DerivedLength/binary,_/binary>> =
         iolist_to_binary(pbkdf2(Password, Salt, Iterations, L, 1, [])),


Mime
View raw message