You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@couchdb.apache.org by "ronnieroyston (via GitHub)" <gi...@apache.org> on 2023/07/03 17:05:34 UTC

[GitHub] [couchdb] ronnieroyston opened a new issue, #4663: Server Admin Role Must Be Explicitly Configured On CouchDB

ronnieroyston opened a new issue, #4663:
URL: https://github.com/apache/couchdb/issues/4663

   # Introduction
   
   I have implemented [JWT authentication](https://docs.couchdb.org/en/stable/api/server/authn.html#jwt-authentication). I noticed that:
   
   (1) Users configured as server administrators are not granted server administrator privileges when authenticating via JWT unless `"_admin"` is included in the JWT payload `roles` parameter.
   
   (2) JWT authenticated users having `"_admin"` included in the JWT payload `roles` parameter are allowed server admin privileges even though this user, or `sub` in JWT parlance, is not configured as a server admin.
   
   When I say "configured as a server admin" I mean that the user will be specified in CouchDB's response to the `_node/_local/_config/admins/` endpoint.
   
   ## Abstract
   
   Server admin privileges should be subject to highest security measures.  Double checking a JWT _claim_ of a users `_admin` role against the list of configured system admins seems worth consideration.
   
   ## Requirements Language
   
   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this
   document are to be interpreted as described in
   [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119.txt).
   
   ## Terminology
   
   **JWT**, JSON Web Token
   **Server admin**, user is listed in response to the `_node/_local/_config/admins/` endpoint
   
   ---
   
   # Detailed Description
   
   The solution would be to implement a verification of JWT claims specific to `roles:["_admin"]`. CouchDB shall validate any user presenting a JWT claim of `_admin`.
   
   # Advantages and Disadvantages
   
   The advantage of this additional security check is that a compromised JWT, while not probable, would not allow an attacker server admin status.
   
   # Key Changes
   
   This existing behavior of trusting `_admin` role claims is not explicitly documented therefore users may not notice the change. A meaningful HTTP error message such as "JWT _admin claim not configured for user" would enable adoption.
   
   ## Applications and Modules affected
   
   [chttpd]
   [admins]
   
   ## HTTP API additions
   
   A meaningful HTTP error message such as "JWT _admin claim not configured for user" 
   
   ## HTTP API deprecations
   
   None.
   
   # Security Considerations
   
   CouchDB security would be enhanced by implementing this additional layer of security.
   
   # References
   
   https://docs.couchdb.org/en/stable/api/server/authn.html#jwt-authentication
   https://docs.couchdb.org/en/stable/intro/security.html#creating-a-new-admin-user
   
   # Acknowledgements
   
   Thanks to the CouchDB team for creating a great product!
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [couchdb] rnewson commented on issue #4663: Server Admin Access Via JWT Claims vs Explicit Configuration

Posted by "rnewson (via GitHub)" <gi...@apache.org>.
rnewson commented on issue #4663:
URL: https://github.com/apache/couchdb/issues/4663#issuecomment-1619052403

   hm, nope, I can't go for that. usernames are not secrets (even if the list of usernames is access controlled).
   
   That leaves us with an option to simply reject JWT tokens with the `_admin` role as an option.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [couchdb] lazedo commented on issue #4663: Server Admin Access Via JWT Claims vs Explicit Configuration

Posted by "lazedo (via GitHub)" <gi...@apache.org>.
lazedo commented on issue #4663:
URL: https://github.com/apache/couchdb/issues/4663#issuecomment-1630379864

   another alternative would be to use `JMESPath` to evaluate the _admins https://github.com/thehangedman/jmespath-erlang


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [couchdb] ronnieroyston commented on issue #4663: Server Admin Access Via JWT Claims vs Explicit Configuration

Posted by "ronnieroyston (via GitHub)" <gi...@apache.org>.
ronnieroyston commented on issue #4663:
URL: https://github.com/apache/couchdb/issues/4663#issuecomment-1619018951

   There is value in validating that the `sub` is configured as a server admin. The particular server admin password can exist even if not used/read for JWT authentication.
   
   As an aside, understood regarding the provenance of the JWT handler.  _Authorization_, or `role` based access, is configured on CouchDB no matter what, e.g. each database's `_security` endpoint, or _permissions_. Mapping users to CouchDB roles seems like it should always exist on CouchDB and developers can architect in this fashion _as-is_ via design documents as far as I understand.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [couchdb] ronnieroyston commented on issue #4663: Server Admin Access Via JWT Claims vs Explicit Configuration

Posted by "ronnieroyston (via GitHub)" <gi...@apache.org>.
ronnieroyston commented on issue #4663:
URL: https://github.com/apache/couchdb/issues/4663#issuecomment-1619039064

   Upon HTTP request, 
   
   1. read/validate JWT
   2. if `sub` `role` exists, splice/remove `_admin` from roles
   3. for each configured server admin 
    3a. If `sub` equals userID push `_admin` to `sub` `roles` array
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [couchdb] rnewson commented on issue #4663: Server Admin Access Via JWT Claims vs Explicit Configuration

Posted by "rnewson (via GitHub)" <gi...@apache.org>.
rnewson commented on issue #4663:
URL: https://github.com/apache/couchdb/issues/4663#issuecomment-1618983984

   The JWT handler (and the much older proxy handler) exists to externalise authentication/authorization decisions, including whether a user has admin privileges. The CouchDB administrator needs to make several privileged changes to enable this behaviour. Enabling the handler iteself, and then populating `[jwt_keys]` they trust to issue JWT tokens.
   
   I'd be happy to merge an enhancement to the handler that rejects JWT tokens with the `_admin` role as an option (off by default for backward compatibility reasons), if you were so minded.
   
   I think what won't work is 'validating' the token against the `[admins]` in the .ini file as that only contains a (salted) password hash; the JWT obviously doesn't include the password that we'd hash to compare it against. Perhaps you have some other idea in mind for this double-check? (though it can't be solely on the _name_ of the admin).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [couchdb] lazedo commented on issue #4663: Server Admin Access Via JWT Claims vs Explicit Configuration

Posted by "lazedo (via GitHub)" <gi...@apache.org>.
lazedo commented on issue #4663:
URL: https://github.com/apache/couchdb/issues/4663#issuecomment-1630265536

   we added a `admin_roles` config. feel free to use/adapt the below (needs rebase)
   
   ```
   diff --git a/src/couch/src/couch_httpd_auth.erl b/src/couch/src/couch_httpd_auth.erl
   index 24a0c15ed..07d4df4f3 100644
   --- a/src/couch/src/couch_httpd_auth.erl
   +++ b/src/couch/src/couch_httpd_auth.erl
   @@ -230,21 +230,10 @@ jwt_authentication_handler(Req) ->
                        case lists:keyfind(<<"sub">>, 1, Claims) of
                            false ->
                                throw({unauthorized, <<"Token missing sub claim.">>});
   -                        {_, User} ->
   -                            Req#httpd{
   -                                user_ctx = #user_ctx{
   -                                    name = User,
   -                                    roles = couch_util:get_value(
   -                                        ?l2b(
   -                                            config:get(
   -                                                "jwt_auth", "roles_claim_name", "_couchdb.roles"
   -                                            )
   -                                        ),
   -                                        Claims,
   -                                        []
   -                                    )
   -                                }
   -                            }
   +                        {_, User} -> Req#httpd{user_ctx=#user_ctx{
   +                            name = User,
   +                            roles = jwt_roles(Claims)
   +                        }}
                        end;
                    {error, Reason} ->
                        throw(Reason)
   @@ -253,6 +242,31 @@ jwt_authentication_handler(Req) ->
                Req
        end.
    
   +jwt_roles(Claims) ->
   +    RolesClaimName = ?l2b(config:get("jwt_auth", "roles_claim_name", "_couchdb.roles")),
   +    JWTRoles = couch_util:get_value(RolesClaimName, Claims, []),
   +    case jwt_admin_roles() of
   +        [] -> lists:usort(JWTRoles);
   +        Roles -> jwt_verify_admin_roles(JWTRoles, Roles)
   +    end.
   +
   +jwt_verify_admin_roles(JWTRoles, Roles) ->
   +    VerifyFun = fun(JWTRole) -> lists:member(JWTRole, Roles) end,
   +    case lists:any(VerifyFun, JWTRoles) of
   +        true -> lists:usort([<<"_admin">> | JWTRoles]);
   +        false -> lists:usort(JWTRoles)
   +    end.
   +
   +jwt_admin_roles() ->
   +    AdminRoles = string:split(config:get("jwt_auth", "admin_roles", ""), ",", all),
   +    lists:filtermap(fun jwt_filter_map_admin_role/1, AdminRoles).
   +
   +jwt_filter_map_admin_role(Role) ->
   +    case string:is_empty(Role) of
   +        true -> false;
   +        false -> {true, ?l2b(Role)}
   +    end.
   +
    get_configured_claims() ->
        Claims = config:get("jwt_auth", "required_claims", ""),
        Re = "((?<key1>[a-z]+)|{(?<key2>[a-z]+)\s*,\s*\"(?<val>[^\"]+)\"})",
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [couchdb] ronnieroyston commented on issue #4663: Server Admin Access Via JWT Claims vs Explicit Configuration

Posted by "ronnieroyston (via GitHub)" <gi...@apache.org>.
ronnieroyston commented on issue #4663:
URL: https://github.com/apache/couchdb/issues/4663#issuecomment-1619065193

   The JWT signature acts as the password. Couch verifying that the `sub` is configured as an `_admin` does not make a username a secret or a password but adds additional security in that server admins must be explicitly configured.
   
   The option to reject `_admin` claims is valuable.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [couchdb] rnewson commented on issue #4663: Server Admin Access Via JWT Claims vs Explicit Configuration

Posted by "rnewson (via GitHub)" <gi...@apache.org>.
rnewson commented on issue #4663:
URL: https://github.com/apache/couchdb/issues/4663#issuecomment-1619027071

   > There is value in validating that the sub is configured as a server admin
   
   How do you propose doing so? (usernames are not secrets).
   
   I do not understand your aside.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org