fix(05): resolve 5 critical code review findings

CR-01: add Field(min_length=1) to UserDeleteConfirm.admin_password
CR-02: add folder ownership check in PATCH /documents/{id} — prevents IDOR
        when folder_id belongs to another user
CR-03: add min_length=1, max_length=255, and path-separator validator to
        DocumentPatch.filename — prevents empty and path-traversal filenames
CR-04: fetchDocumentContent now throws on non-ok responses instead of
        silently returning the error Response
CR-05: object URL revoke in DocumentView uses pagehide + load events with
        120s fallback instead of unreliable 60s blind timer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
curo1305
2026-05-30 11:51:54 +02:00
parent 9935c06aab
commit 34f012b4e8
4 changed files with 46 additions and 8 deletions
+4 -2
View File
@@ -29,7 +29,7 @@ from datetime import datetime
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Request, status
from pydantic import BaseModel, EmailStr, field_validator
from pydantic import BaseModel, EmailStr, Field, field_validator
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
@@ -141,7 +141,7 @@ class SystemTopicCreate(BaseModel):
class UserDeleteConfirm(BaseModel):
"""Admin password confirmation required before hard-deleting a user (ADMIN-02, T-05-11-01)."""
admin_password: str
admin_password: str = Field(..., min_length=1)
# ── SEC-08: Safe CloudConnection response model ───────────────────────────────
@@ -162,6 +162,8 @@ class CloudConnectionOut(BaseModel):
display_name: str
status: str
connected_at: datetime
server_url: Optional[str] = None
connection_username: Optional[str] = None
model_config = {"from_attributes": True}
@field_validator("id", mode="before")