From 22a53499ecb4156157e430f7f61f72f59e723a5a Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 30 Mar 2022 10:12:46 +0300 Subject: [PATCH] Add a deprecation warning when jwt.decode() is called with the legacy verify= argument Since the arbitrary/unused `**kwargs` can't quite be dropped (as #657 would do) without a major version bump (as reverted in #701), it's still a good idea to warn users if they are attempting to use contradictory arguments for the security-sensitive `verify=` argument. --- jwt/api_jwt.py | 12 ++++++++++++ tests/test_api_jwt.py | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/jwt/api_jwt.py b/jwt/api_jwt.py index c9d34a5f..da9d481b 100644 --- a/jwt/api_jwt.py +++ b/jwt/api_jwt.py @@ -1,4 +1,5 @@ import json +import warnings from calendar import timegm from collections.abc import Iterable, Mapping from datetime import datetime, timedelta, timezone @@ -75,6 +76,17 @@ def decode_complete( else: options.setdefault("verify_signature", True) + # If the user has set the legacy `verify` argument, and it doesn't match + # what the relevant `options` entry for the argument is, inform the user + # that they're likely making a mistake. + if "verify" in kwargs and kwargs["verify"] != options["verify_signature"]: + warnings.warn( + "The `verify` argument to `decode` does nothing in PyJWT 2.0 and newer. " + "The equivalent is setting `verify_signature` to False in the `options` dictionary. " + "This invocation has a mismatch between the kwarg and the option entry.", + category=DeprecationWarning, + ) + if not options["verify_signature"]: options.setdefault("verify_exp", False) options.setdefault("verify_nbf", False) diff --git a/tests/test_api_jwt.py b/tests/test_api_jwt.py index fa3167a4..57cc4ae1 100644 --- a/tests/test_api_jwt.py +++ b/tests/test_api_jwt.py @@ -658,3 +658,19 @@ def test_decode_no_algorithms_verify_signature_false(self, jwt, payload): jwt_message = jwt.encode(payload, secret) jwt.decode(jwt_message, secret, options={"verify_signature": False}) + + def test_decode_legacy_verify_warning(self, jwt, payload): + secret = "secret" + jwt_message = jwt.encode(payload, secret) + + with pytest.deprecated_call(): + # The implicit default for options.verify_signature is True, + # but the user sets verify to False. + jwt.decode(jwt_message, secret, verify=False, algorithms=["HS256"]) + + with pytest.deprecated_call(): + # The user explicitly sets verify=True, + # but contradicts it in verify_signature. + jwt.decode( + jwt_message, secret, verify=True, options={"verify_signature": False} + )