diff --git a/api/config/settings/common.py b/api/config/settings/common.py index d0ff2e188..360346b27 100644 --- a/api/config/settings/common.py +++ b/api/config/settings/common.py @@ -564,12 +564,19 @@ CELERY_BEAT_SCHEDULE = { NODEINFO_REFRESH_DELAY = env.int("NODEINFO_REFRESH_DELAY", default=3600 * 24) + +def get_user_secret_key(user): + from django.conf import settings + + return settings.SECRET_KEY + str(user.secret_key) + + JWT_AUTH = { "JWT_ALLOW_REFRESH": True, "JWT_EXPIRATION_DELTA": datetime.timedelta(days=7), "JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(days=30), "JWT_AUTH_HEADER_PREFIX": "JWT", - "JWT_GET_USER_SECRET_KEY": lambda user: user.secret_key, + "JWT_GET_USER_SECRET_KEY": get_user_secret_key, } OLD_PASSWORD_FIELD_ENABLED = True ACCOUNT_ADAPTER = "funkwhale_api.users.adapters.FunkwhaleAccountAdapter" diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py index 51ee01a81..ed40017cc 100644 --- a/api/funkwhale_api/federation/serializers.py +++ b/api/funkwhale_api/federation/serializers.py @@ -1012,7 +1012,7 @@ class TrackSerializer(MusicEntitySerializer): metadata = music_tasks.federation_audio_track_to_metadata( validated_data, references ) - metadata['tags'] = tags + metadata["tags"] = tags from_activity = self.context.get("activity") if from_activity: diff --git a/api/tests/users/test_jwt.py b/api/tests/users/test_jwt.py index 83de757c8..d0fe1a1fa 100644 --- a/api/tests/users/test_jwt.py +++ b/api/tests/users/test_jwt.py @@ -22,3 +22,22 @@ def test_can_invalidate_token_when_changing_user_secret_key(factories): # token should be invalid with pytest.raises(DecodeError): api_settings.JWT_DECODE_HANDLER(payload) + + +def test_can_invalidate_token_when_changing_settings_secret_key(factories, settings): + settings.SECRET_KEY = "test1" + user = factories["users.User"]() + jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER + jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER + payload = jwt_payload_handler(user) + payload = jwt_encode_handler(payload) + + # this should work + api_settings.JWT_DECODE_HANDLER(payload) + + # now we update the secret key + settings.SECRET_KEY = "test2" + + # token should be invalid + with pytest.raises(DecodeError): + api_settings.JWT_DECODE_HANDLER(payload) diff --git a/changes/changelog.d/jwt.enhancement b/changes/changelog.d/jwt.enhancement new file mode 100644 index 000000000..0ce222251 --- /dev/null +++ b/changes/changelog.d/jwt.enhancement @@ -0,0 +1 @@ +Increase the security of JWT token generation by using DJANGO_SECRET_KEY as well as user-specific salt for the signature