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

jaydoane pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 73413346c1e0c4fb94c68b62ffc3656888723f41
Author: Jay Doane <[email protected]>
AuthorDate: Mon Mar 1 13:48:19 2021 -0800

    Ignore unchecked JWT claims
    
    Previously, if a JWT claim was present, it was validated regardless of
    whether it was required.
    
    However, according to the spec [1]:
    
    "all claims that are not understood by implementations MUST be ignored"
    
    which we interpret to mean that we should not attempt to validate
    claims we don't require.
    
    With this change, only claims listed in required checks are validated.
    
    [1] https://tools.ietf.org/html/rfc7519#section-4
---
 src/jwtf/src/jwtf.erl | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/jwtf/src/jwtf.erl b/src/jwtf/src/jwtf.erl
index 247f2b5..a0bbf1f 100644
--- a/src/jwtf/src/jwtf.erl
+++ b/src/jwtf/src/jwtf.erl
@@ -188,8 +188,7 @@ validate_alg(Props, Checks) ->
     end.
 
 
-%% Not all these fields have to be present, but if they _are_ present
-%% they must be valid.
+%% Only validate required checks.
 validate_payload(Props, Checks) ->
     validate_iss(Props, Checks),
     validate_iat(Props, Checks),
@@ -202,7 +201,7 @@ validate_iss(Props, Checks) ->
     ActualISS = prop(<<"iss">>, Props),
 
     case {ExpectedISS, ActualISS} of
-        {undefined, undefined} ->
+        {undefined, _} -> % ignore unrequired check
             ok;
         {ISS, undefined} when ISS /= undefined ->
             throw({bad_request, <<"Missing iss claim">>});
@@ -218,11 +217,11 @@ validate_iat(Props, Checks) ->
     IAT = prop(<<"iat">>, Props),
 
     case {Required, IAT} of
-        {undefined, undefined} ->
+        {undefined, _} -> % ignore unrequired check
             ok;
         {true, undefined} ->
             throw({bad_request, <<"Missing iat claim">>});
-        {_, IAT} when is_integer(IAT) ->
+        {true, IAT} when is_integer(IAT) ->
             ok;
         {true, _} ->
             throw({bad_request, <<"Invalid iat claim">>})
@@ -234,12 +233,12 @@ validate_nbf(Props, Checks) ->
     NBF = prop(<<"nbf">>, Props),
 
     case {Required, NBF} of
-        {undefined, undefined} ->
+        {undefined, _} -> % ignore unrequired check
             ok;
         {true, undefined} ->
             throw({bad_request, <<"Missing nbf claim">>});
-        {_, IAT} ->
-            assert_past(<<"nbf">>, IAT)
+        {true, NBF} ->
+            assert_past(<<"nbf">>, NBF)
     end.
 
 
@@ -248,11 +247,11 @@ validate_exp(Props, Checks) ->
     EXP = prop(<<"exp">>, Props),
 
     case {Required, EXP} of
-        {undefined, undefined} ->
+        {undefined, _} -> % ignore unrequired check
             ok;
         {true, undefined} ->
             throw({bad_request, <<"Missing exp claim">>});
-        {_, EXP} ->
+        {true, EXP} ->
             assert_future(<<"exp">>, EXP)
     end.
 
@@ -351,3 +350,20 @@ now_seconds() ->
 
 prop(Prop, Props) ->
     proplists:get_value(Prop, Props).
+
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+
+validate_payload_ignore_unchecked_props_test() ->
+    ?assertEqual(ok, validate_payload(_Props = [], _Checks = [])),
+    BogusProps = [
+        {iss, bogus},
+        {iat, bogus},
+        {nbf, bogus},
+        {exp, bogus}
+    ],
+    ?assertEqual(ok, validate_payload(BogusProps, _Checks = [])),
+    ok.
+
+-endif.

Reply via email to