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.
