Harden secret key configuration
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
DEVELOPMENT_SECRET_KEY = "dev-secret-key-change-me"
|
||||
UNSAFE_SECRET_KEYS = {
|
||||
"",
|
||||
"change-me",
|
||||
"dev-secret-key-change-me",
|
||||
"secret",
|
||||
"default",
|
||||
}
|
||||
|
||||
|
||||
def _get_bool_setting(name: str, default: bool) -> bool:
|
||||
"""Parse conventional boolean environment values."""
|
||||
@@ -23,10 +32,46 @@ def _get_max_content_length() -> int:
|
||||
return 100 * 1024 * 1024
|
||||
|
||||
|
||||
def _get_app_env() -> str:
|
||||
"""Resolve the effective application environment."""
|
||||
return (
|
||||
os.environ.get("APP_ENV")
|
||||
or os.environ.get("FLASK_ENV")
|
||||
or "production"
|
||||
).strip().lower()
|
||||
|
||||
|
||||
def _is_development_env() -> bool:
|
||||
"""Return whether the app is explicitly running in development mode."""
|
||||
return _get_app_env() == "development"
|
||||
|
||||
|
||||
def _get_secret_key() -> str:
|
||||
"""Resolve the secret key with a development-only fallback."""
|
||||
secret_key = os.environ.get("SECRET_KEY", "").strip()
|
||||
if secret_key:
|
||||
return secret_key
|
||||
if _is_development_env():
|
||||
return DEVELOPMENT_SECRET_KEY
|
||||
return ""
|
||||
|
||||
|
||||
def validate_secret_key(secret_key: str) -> None:
|
||||
"""Fail fast when a production-like environment uses an unsafe secret key."""
|
||||
normalized = secret_key.strip()
|
||||
if _is_development_env():
|
||||
return
|
||||
if normalized.lower() in UNSAFE_SECRET_KEYS:
|
||||
raise RuntimeError(
|
||||
"SECRET_KEY is missing or unsafe for a production-like environment. "
|
||||
"Set SECRET_KEY to a long random value, or use APP_ENV=development only for local development."
|
||||
)
|
||||
|
||||
|
||||
class Config:
|
||||
"""Default configuration for local and container usage."""
|
||||
|
||||
SECRET_KEY = os.environ.get("SECRET_KEY", "dev-secret-key-change-me")
|
||||
SECRET_KEY = _get_secret_key()
|
||||
# Default to 100 MiB so larger WAF exports can be processed without tuning.
|
||||
MAX_CONTENT_LENGTH = _get_max_content_length()
|
||||
PREVIEW_RECORD_LIMIT = int(os.environ.get("PREVIEW_RECORD_LIMIT", 5))
|
||||
|
||||
Reference in New Issue
Block a user