fixed some security risks

This commit is contained in:
2026-02-21 10:36:53 -05:00
parent b62df442b5
commit c2fe59da0d
8 changed files with 170 additions and 250 deletions
+41 -17
View File
@@ -1,46 +1,70 @@
import os
from datetime import timedelta
from dotenv import load_dotenv
# Load .env from the project root (only takes effect locally; no-op in production
# if variables are already set in the environment)
load_dotenv()
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
# Secret key for session management
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key-change-in-production'
# Database configuration
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'mysql+pymysql://jqc_admin:Jqc4dm1n141!@localhost/janitorial_qc'
def _require_env(key: str) -> str:
"""Return the value of a required environment variable, raising if absent."""
value = os.environ.get(key)
if not value:
raise RuntimeError(
f"Required environment variable '{key}' is not set. "
f"Add it to your .env file (development) or server environment (production)."
)
return value
class Config:
# ── Security ────────────────────────────────────────────────────────────
# SECRET_KEY must be set externally — no insecure fallback.
SECRET_KEY = _require_env('SECRET_KEY')
# ── Database ────────────────────────────────────────────────────────────
# DATABASE_URL must be set externally — no hardcoded credentials.
SQLALCHEMY_DATABASE_URI = _require_env('DATABASE_URL')
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = False
# Upload configuration
# ── File uploads ────────────────────────────────────────────────────────
UPLOAD_FOLDER = os.path.join(basedir, 'app/static/uploads')
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB max file size
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16 MB
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
# Session configuration
# ── Session / cookies ───────────────────────────────────────────────────
PERMANENT_SESSION_LIFETIME = timedelta(hours=24)
SESSION_COOKIE_SECURE = False # Change to True on production
# Secure by default — subclasses must explicitly opt out for local dev.
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
# Mail configuration (configure later)
MAIL_SERVER = os.environ.get('MAIL_SERVER')
MAIL_PORT = int(os.environ.get('MAIL_PORT') or 587)
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS', 'true').lower() in ['true', 'on', '1']
# ── Mail ────────────────────────────────────────────────────────────────
MAIL_SERVER = os.environ.get('MAIL_SERVER')
MAIL_PORT = int(os.environ.get('MAIL_PORT') or 587)
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS', 'true').lower() in ('true', 'on', '1')
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
class DevelopmentConfig(Config):
DEBUG = True
SQLALCHEMY_ECHO = True
# Allow HTTP cookies during local development (HTTP, not HTTPS)
SESSION_COOKIE_SECURE = False
class ProductionConfig(Config):
DEBUG = False
SESSION_COOKIE_SECURE = True
# Inherits SESSION_COOKIE_SECURE = True from Config — no override needed.
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
'production': ProductionConfig,
'default': DevelopmentConfig,
}