fix: address multiple code audit findings

- CORS: replace wildcard with explicit origin list from CORS_ORIGINS env
- Auth: enforce strong defaults, JWT blacklist (RevokedToken model), login rate limiting
- Auth: validate password length before bcrypt (72-byte limit)
- Scheduler: single-threaded worker to mitigate SQLite write contention
- Scheduler: graceful shutdown (wait=True)
- Snapshots: add prune_snapshots() with configurable retention count
- Storage: isolate localStorage keys via VITE_APP_KEY prefix
- Config: add cors_origins, login_rate_limit, snapshot_retention_count settings
This commit is contained in:
SmartUp Developer
2026-05-17 10:52:18 +08:00
parent a42ecf7bcc
commit ad16618406
25 changed files with 792 additions and 165 deletions
+10 -2
View File
@@ -4,9 +4,13 @@ from functools import lru_cache
class Settings(BaseSettings):
admin_email: str = "admin@smartup.local"
admin_password: str = "changeme"
jwt_secret: str = "change-me-in-production"
admin_password: str = ""
jwt_secret: str = ""
jwt_expire_hours: int = 24
cors_origins: str = "http://localhost:8899,http://127.0.0.1:8899"
login_rate_limit_attempts: int = 5
login_rate_limit_window_seconds: int = 300
snapshot_retention_count: int = 500
database_url: str = "sqlite:////app/data/app.db"
tz: str = "Asia/Shanghai"
# consecutive failures before upstream goes unhealthy
@@ -14,6 +18,10 @@ class Settings(BaseSettings):
browser_profiles_dir: str = "/app/data/browser-profiles"
browser_headless: bool = True
@property
def cors_origin_list(self) -> list[str]:
return [item.strip() for item in self.cors_origins.split(",") if item.strip()]
model_config = {"env_file": ".env", "case_sensitive": False, "extra": "ignore"}