Phase 1: Critical security fixes - 59 permissions, grants, RLS, mass-assignment, ownership, leaks, MIME
Check Cross-Plugin Imports / check (push) Has been cancelled

This commit is contained in:
Agent Zero
2026-08-03 22:32:03 +02:00
parent bd9fc15418
commit 4f970a11eb
9 changed files with 302 additions and 3 deletions
+59
View File
@@ -86,6 +86,60 @@ async def create_entity_permission(
raise HTTPException(status_code=400, detail=str(e))
async def _check_entity_ownership(
db: AsyncSession,
tenant_id: uuid.UUID,
user_id: uuid.UUID,
entity_type: str,
entity_id: str,
is_system_admin: bool,
) -> None:
"""Verify that the current user owns the entity or is system admin.
Raises 403 if the user is neither owner nor system admin.
"""
if is_system_admin:
return
from app.models.entity_permission import ENTITY_MODELS
from sqlalchemy import select
model_info = ENTITY_MODELS.get(entity_type)
if model_info is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={"detail": f"Unknown entity type: {entity_type}", "code": "not_found"},
)
model = model_info["model"]
try:
eid = uuid.UUID(entity_id)
except ValueError:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={"detail": "Invalid entity_id", "code": "invalid_id"},
) from None
result = await db.execute(
select(model.owner_id).where(
model.id == eid,
model.tenant_id == tenant_id,
)
)
row = result.first()
if row is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={"detail": "Entity not found", "code": "not_found"},
)
owner_id = row[0]
if owner_id is not None and owner_id != user_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail={"detail": "Only the entity owner or system admin can modify permissions", "code": "forbidden"},
)
@router.put("/{entity_type}/{entity_id}/{permission_id}")
async def update_entity_permission(
entity_type: str,
@@ -103,6 +157,11 @@ async def update_entity_permission(
_PERM_RATE_LIMIT_MAX,
_PERM_RATE_LIMIT_WINDOW,
)
# Ownership check: only owner or system admin can update permissions
await _check_entity_ownership(
db, tenant_id, user_id, entity_type, entity_id,
current_user.get("is_system_admin", False),
)
try:
return await entity_permission_service.update_permission(
db,