From b8c7c035280c97cd360d58e5a89591649de1501f Mon Sep 17 00:00:00 2001 From: All Asmaul Husnain <2263081025@uttarauniversity.edu.bd> Date: Sat, 24 Oct 2026 11:05:27 +0600 Subject: [PATCH 1/3] fix: reject example JWT placeholder in production --- app/config.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/config.py b/app/config.py index 31f277c..6187e27 100644 --- a/app/config.py +++ b/app/config.py @@ -37,8 +37,15 @@ def validate_secrets(self) -> "Settings": if self.environment.lower() != "production": return self - if self.jwt_secret == "change-this-in-production" or len(self.jwt_secret) < 32: - raise ValueError("Production JWT_SECRET must not use the default and must be at least 32 characters") + jwt_secret = self.jwt_secret.strip() + known_jwt_placeholders = { + "change-this-in-production", + "replace-with-a-long-random-secret", + } + if jwt_secret.lower() in known_jwt_placeholders or len(jwt_secret) < 32: + raise ValueError( + "Production JWT_SECRET must not use a placeholder and must be at least 32 characters" + ) try: Fernet(self.encryption_key.encode()) From c82ab0fbfb90df23b67c4dbd13467d337c8c951b Mon Sep 17 00:00:00 2001 From: All Asmaul Husnain <2263081025@uttarauniversity.edu.bd> Date: Sat, 24 Oct 2026 11:05:32 +0600 Subject: [PATCH 2/3] test: reject JWT placeholder from env example --- tests/test_config.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/test_config.py b/tests/test_config.py index 34141e8..069bb33 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,3 +1,5 @@ +from pathlib import Path + import pytest from cryptography.fernet import Fernet from pydantic import ValidationError @@ -14,6 +16,21 @@ def test_production_rejects_default_jwt_secret() -> None: ) +def test_production_rejects_jwt_placeholder_from_env_example() -> None: + jwt_secret = next( + line.partition("=")[2] + for line in Path(".env.example").read_text(encoding="utf-8").splitlines() + if line.startswith("JWT_SECRET=") + ) + + with pytest.raises(ValidationError, match="Production JWT_SECRET"): + Settings( + environment="production", + jwt_secret=jwt_secret, + encryption_key=Fernet.generate_key().decode(), + ) + + def test_production_requires_a_valid_fernet_key() -> None: with pytest.raises(ValidationError, match="Production ENCRYPTION_KEY"): Settings( @@ -90,6 +107,7 @@ def test_environment_rejects_unknown_values() -> None: with pytest.raises(ValidationError, match="environment"): Settings(environment="prod") + def test_production_requires_database_tls() -> None: with pytest.raises(ValidationError, match="must enable PostgreSQL TLS"): Settings( @@ -99,4 +117,3 @@ def test_production_requires_database_tls() -> None: encryption_key=Fernet.generate_key().decode(), rate_limit_storage_uri="redis://localhost:6379/0", ) - From fc351332297414600594c5652757d52abaf6c765 Mon Sep 17 00:00:00 2001 From: All Asmaul Husnain <2263081025@uttarauniversity.edu.bd> Date: Sat, 24 Oct 2026 11:06:13 +0600 Subject: [PATCH 3/3] test: resolve env example relative to test file --- tests/test_config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_config.py b/tests/test_config.py index 069bb33..a44ba83 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -17,9 +17,10 @@ def test_production_rejects_default_jwt_secret() -> None: def test_production_rejects_jwt_placeholder_from_env_example() -> None: + example_file = Path(__file__).resolve().parents[1] / ".env.example" jwt_secret = next( line.partition("=")[2] - for line in Path(".env.example").read_text(encoding="utf-8").splitlines() + for line in example_file.read_text(encoding="utf-8").splitlines() if line.startswith("JWT_SECRET=") )