fix: critical security hardening (Phase A permissions audit)
- Remove role field from UserCreate schema, hardcode 'engineer' at registration
- Escape all user content in HTML export with html.escape() (XSS fix)
- Add field_validator to reject default SECRET_KEY when DEBUG=False
- Add CHECK constraint on users.role ('engineer'|'viewer') + migration 011
- Fix test_admin fixture to properly grant is_super_admin via ORM
- Fix circular FK (users↔invite_codes) in test DB setup with DROP SCHEMA CASCADE
- Add 5 new security tests (role validation + XSS prevention)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,9 @@ from pydantic import field_validator
|
||||
from typing import Optional
|
||||
|
||||
|
||||
_DEFAULT_SECRET_KEY = "your-secret-key-change-in-production-use-openssl-rand-hex-32"
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
# Application
|
||||
APP_NAME: str = "ResolutionFlow"
|
||||
@@ -26,7 +29,19 @@ class Settings(BaseSettings):
|
||||
return self.DATABASE_URL.replace("postgresql+asyncpg://", "postgresql://", 1)
|
||||
|
||||
# JWT Settings
|
||||
SECRET_KEY: str = "your-secret-key-change-in-production-use-openssl-rand-hex-32"
|
||||
SECRET_KEY: str = _DEFAULT_SECRET_KEY
|
||||
|
||||
@field_validator("SECRET_KEY", mode="after")
|
||||
@classmethod
|
||||
def reject_default_secret_in_production(cls, v: str, info) -> str:
|
||||
"""Fail loudly if the default secret key is used outside of DEBUG mode."""
|
||||
debug = info.data.get("DEBUG", False)
|
||||
if v == _DEFAULT_SECRET_KEY and not debug:
|
||||
raise ValueError(
|
||||
"SECRET_KEY must be set to a secure value in production. "
|
||||
"Generate one with: openssl rand -hex 32"
|
||||
)
|
||||
return v
|
||||
ALGORITHM: str = "HS256"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 15
|
||||
REFRESH_TOKEN_EXPIRE_DAYS: int = 7
|
||||
|
||||
Reference in New Issue
Block a user