diff --git a/backend/api/audit.py b/backend/api/audit.py index 91778b6..6884050 100644 --- a/backend/api/audit.py +++ b/backend/api/audit.py @@ -43,6 +43,8 @@ from storage.minio_backend import MinIOBackend router = APIRouter(prefix="/api/admin", tags=["audit"]) +_VALID_EVENT_PREFIXES = frozenset({"auth", "document", "folder", "share", "admin", "cloud"}) + # ── Safe response helpers ───────────────────────────────────────────────────── @@ -121,7 +123,9 @@ def _build_filtered_query( if user_id is not None: q = q.where(AuditLog.user_id == user_id) if event_type is not None: - q = q.where(AuditLog.event_type.like(f"{event_type}%")) + if event_type not in _VALID_EVENT_PREFIXES: + raise HTTPException(status_code=422, detail="Invalid event_type prefix") + q = q.where(AuditLog.event_type.like(f"{event_type}.%")) return q @@ -161,7 +165,9 @@ def _build_filtered_query_with_handles( if user_uuid is not None: q = q.where(AuditLog.user_id == user_uuid) if event_type is not None: - q = q.where(AuditLog.event_type.like(f"{event_type}%")) + if event_type not in _VALID_EVENT_PREFIXES: + raise HTTPException(status_code=422, detail="Invalid event_type prefix") + q = q.where(AuditLog.event_type.like(f"{event_type}.%")) return q @@ -288,7 +294,9 @@ async def list_audit_log( if user_uuid is not None: count_q = count_q.where(AuditLog.user_id == user_uuid) if event_type is not None: - count_q = count_q.where(AuditLog.event_type.like(f"{event_type}%")) + if event_type not in _VALID_EVENT_PREFIXES: + raise HTTPException(status_code=422, detail="Invalid event_type prefix") + count_q = count_q.where(AuditLog.event_type.like(f"{event_type}.%")) count_result = await session.execute(count_q) total = count_result.scalar_one()