feat: implement 5 QA-driven security and quality proposals
Implemented proposals from comprehensive QA review: 1. extend-csrf-protection - Add POST to CSRF protected methods in frontend - Global CSRF middleware for all state-changing operations - Update tests with CSRF token fixtures 2. tighten-cors-websocket-security - Replace wildcard CORS with explicit method/header lists - Disable query parameter auth in production (code 4002) - Add per-user WebSocket connection limit (max 5, code 4005) 3. shorten-jwt-expiry - Reduce JWT expiry from 7 days to 60 minutes - Add refresh token support with 7-day expiry - Implement token rotation on refresh - Frontend auto-refresh when token near expiry (<5 min) 4. fix-frontend-quality - Add React.lazy() code splitting for all pages - Fix useCallback dependency arrays (Dashboard, Comments) - Add localStorage data validation in AuthContext - Complete i18n for AttachmentUpload component 5. enhance-backend-validation - Add SecurityAuditMiddleware for access denied logging - Add ErrorSanitizerMiddleware for production error messages - Protect /health/detailed with admin authentication - Add input length validation (comment 5000, desc 10000) All 521 backend tests passing. Frontend builds successfully. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import datetime
|
||||
from fastapi import FastAPI, Request, APIRouter
|
||||
from fastapi import FastAPI, Request, APIRouter, Depends
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
from slowapi import _rate_limit_exceeded_handler
|
||||
@@ -9,6 +9,9 @@ from slowapi.errors import RateLimitExceeded
|
||||
from sqlalchemy import text
|
||||
|
||||
from app.middleware.audit import AuditMiddleware
|
||||
from app.middleware.csrf import CSRFMiddleware
|
||||
from app.middleware.security_audit import SecurityAuditMiddleware
|
||||
from app.middleware.error_sanitizer import ErrorSanitizerMiddleware
|
||||
from app.core.scheduler import start_scheduler, shutdown_scheduler, scheduler
|
||||
from app.core.rate_limiter import limiter
|
||||
from app.core.deprecation import DeprecationMiddleware
|
||||
@@ -61,6 +64,8 @@ from app.core.database import get_pool_status, engine
|
||||
from app.core.redis import redis_client
|
||||
from app.services.notification_service import get_redis_fallback_status
|
||||
from app.services.file_storage_service import file_storage_service
|
||||
from app.middleware.auth import require_system_admin
|
||||
from app.models import User
|
||||
|
||||
app = FastAPI(
|
||||
title="Project Control API",
|
||||
@@ -73,18 +78,28 @@ app = FastAPI(
|
||||
app.state.limiter = limiter
|
||||
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
||||
|
||||
# CORS middleware
|
||||
# CORS middleware - Explicit methods and headers for security
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=settings.CORS_ORIGINS,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
||||
allow_headers=["Content-Type", "Authorization", "X-CSRF-Token", "X-Request-ID"],
|
||||
)
|
||||
|
||||
# Error sanitizer middleware - sanitizes error messages in production
|
||||
# Must be first in the chain to intercept all error responses
|
||||
app.add_middleware(ErrorSanitizerMiddleware)
|
||||
|
||||
# Audit middleware - extracts request metadata for audit logging
|
||||
app.add_middleware(AuditMiddleware)
|
||||
|
||||
# Security audit middleware - logs 401/403 responses to audit trail
|
||||
app.add_middleware(SecurityAuditMiddleware)
|
||||
|
||||
# CSRF middleware - validates CSRF tokens for state-changing requests
|
||||
app.add_middleware(CSRFMiddleware)
|
||||
|
||||
# Deprecation middleware - adds deprecation headers to legacy /api/ routes
|
||||
app.add_middleware(DeprecationMiddleware)
|
||||
|
||||
@@ -252,14 +267,20 @@ async def readiness_check():
|
||||
|
||||
|
||||
@app.get("/health/detailed")
|
||||
async def detailed_health_check():
|
||||
"""Detailed health check endpoint.
|
||||
async def detailed_health_check(
|
||||
current_user: User = Depends(require_system_admin),
|
||||
):
|
||||
"""Detailed health check endpoint (requires system admin).
|
||||
|
||||
Returns comprehensive status of all system components:
|
||||
- database: Connection pool status and connectivity
|
||||
- redis: Connection status and fallback queue status
|
||||
- storage: File storage validation status
|
||||
- scheduler: Background job scheduler status
|
||||
|
||||
Note: This endpoint requires system admin authentication because it exposes
|
||||
sensitive infrastructure details including connection pool statistics and
|
||||
internal service states.
|
||||
"""
|
||||
db_health = check_database_health()
|
||||
redis_health = check_redis_health()
|
||||
|
||||
Reference in New Issue
Block a user