summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Doane <jaydoane@apache.org>2021-03-01 13:48:19 -0800
committerJay Doane <jay.s.doane@gmail.com>2021-03-15 09:32:10 -0700
commit73413346c1e0c4fb94c68b62ffc3656888723f41 (patch)
tree20112787e0a094fb4d6fc78911fcf9cd117a8b93
parent6fa2a6f8fccbee831ef05e847b7d9acdee8079ab (diff)
downloadcouchdb-73413346c1e0c4fb94c68b62ffc3656888723f41.tar.gz
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
-rw-r--r--src/jwtf/src/jwtf.erl36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/jwtf/src/jwtf.erl b/src/jwtf/src/jwtf.erl
index 247f2b508..a0bbf1fc1 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.