mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
fix: Authenticated IDOR in Dashboard update endpoints allows cross-user Dashboard modification
This commit is contained in:
@@ -6,6 +6,7 @@ from apps.dashboard.crud.dashboard_service import list_resource, load_resource,
|
||||
create_resource, create_canvas, validate_name, delete_resource, update_resource, update_canvas
|
||||
from apps.dashboard.models.dashboard_model import CreateDashboard, BaseDashboard, QueryDashboard
|
||||
from apps.swagger.i18n import PLACEHOLDER_PREFIX
|
||||
from apps.system.schemas.permission import SqlbotPermission, require_permissions
|
||||
from common.audit.models.log_model import OperationType, OperationModules
|
||||
from common.audit.schemas.logger_decorator import LogConfig, system_log
|
||||
from common.core.deps import SessionDep, CurrentUser
|
||||
@@ -19,15 +20,9 @@ async def list_resource_api(session: SessionDep, dashboard: QueryDashboard, curr
|
||||
|
||||
|
||||
@router.post("/load_resource", summary=f"{PLACEHOLDER_PREFIX}load_resource_api")
|
||||
@require_permissions(permission=SqlbotPermission(type='dashboard', keyExpression="dashboard.id"))
|
||||
async def load_resource_api(session: SessionDep, current_user: CurrentUser, dashboard: QueryDashboard):
|
||||
resource_dict = load_resource(session=session, dashboard=dashboard)
|
||||
if resource_dict and resource_dict.get("create_by") != str(current_user.id):
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail="You do not have permission to access this resource"
|
||||
)
|
||||
|
||||
return resource_dict
|
||||
return load_resource(session=session, dashboard=dashboard)
|
||||
|
||||
|
||||
@router.post("/create_resource", response_model=BaseDashboard, summary=f"{PLACEHOLDER_PREFIX}create_resource_api")
|
||||
@@ -36,6 +31,7 @@ async def create_resource_api(session: SessionDep, user: CurrentUser, dashboard:
|
||||
|
||||
|
||||
@router.post("/update_resource", response_model=BaseDashboard, summary=f"{PLACEHOLDER_PREFIX}update_resource")
|
||||
@require_permissions(permission=SqlbotPermission(type='dashboard', keyExpression="dashboard.id"))
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.UPDATE,
|
||||
module=OperationModules.DASHBOARD,
|
||||
@@ -46,6 +42,7 @@ async def update_resource_api(session: SessionDep, user: CurrentUser, dashboard:
|
||||
|
||||
|
||||
@router.delete("/delete_resource/{resource_id}/{name}", summary=f"{PLACEHOLDER_PREFIX}delete_resource_api")
|
||||
@require_permissions(permission=SqlbotPermission(type='dashboard', keyExpression="resource_id"))
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.DELETE,
|
||||
module=OperationModules.DASHBOARD,
|
||||
@@ -67,6 +64,7 @@ async def create_canvas_api(session: SessionDep, user: CurrentUser, dashboard: C
|
||||
|
||||
|
||||
@router.post("/update_canvas", response_model=BaseDashboard, summary=f"{PLACEHOLDER_PREFIX}update_canvas_api")
|
||||
@require_permissions(permission=SqlbotPermission(type='dashboard', keyExpression="dashboard.id"))
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.UPDATE,
|
||||
module=OperationModules.DASHBOARD,
|
||||
|
||||
@@ -79,16 +79,7 @@ def create_resource(session: SessionDep, user: CurrentUser, dashboard: CreateDas
|
||||
|
||||
|
||||
def update_resource(session: SessionDep, user: CurrentUser, dashboard: QueryDashboard):
|
||||
# 添加权限检查:只能更新自己创建的、且在自己工作空间的 Dashboard
|
||||
record = session.query(CoreDashboard).filter(
|
||||
CoreDashboard.id == dashboard.id,
|
||||
CoreDashboard.create_by == str(user.id),
|
||||
CoreDashboard.workspace_id == str(user.oid if user.oid is not None else 1)
|
||||
).first()
|
||||
|
||||
if not record:
|
||||
raise ValueError(f"Dashboard with id {dashboard.id} does not exist or you do not have permission to update it")
|
||||
|
||||
record = session.query(CoreDashboard).filter(CoreDashboard.id == dashboard.id).first()
|
||||
record.name = dashboard.name
|
||||
record.update_by = user.id
|
||||
record.update_time = int(time.time())
|
||||
@@ -111,16 +102,7 @@ def create_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashb
|
||||
|
||||
|
||||
def update_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
|
||||
# 添加权限检查:只能更新自己创建的、且在自己工作空间的 Dashboard
|
||||
record = session.query(CoreDashboard).filter(
|
||||
CoreDashboard.id == dashboard.id,
|
||||
CoreDashboard.create_by == str(user.id),
|
||||
CoreDashboard.workspace_id == str(user.oid if user.oid is not None else 1)
|
||||
).first()
|
||||
|
||||
if not record:
|
||||
raise ValueError(f"Dashboard with id {dashboard.id} does not exist or you do not have permission to update it")
|
||||
|
||||
record = session.query(CoreDashboard).filter(CoreDashboard.id == dashboard.id).first()
|
||||
record.name = dashboard.name
|
||||
record.update_by = user.id
|
||||
record.update_time = int(time.time())
|
||||
@@ -167,8 +149,6 @@ def delete_resource(session: SessionDep, current_user: CurrentUser, resource_id:
|
||||
coreDashboard = session.get(CoreDashboard, resource_id)
|
||||
if not coreDashboard:
|
||||
raise ValueError(f"Resource with id {resource_id} does not exist")
|
||||
if coreDashboard.create_by != str(current_user.id):
|
||||
raise ValueError(f"Resource with id {resource_id} not owned by the current user")
|
||||
sql = text("DELETE FROM core_dashboard WHERE id = :resource_id")
|
||||
result = session.execute(sql, {"resource_id": resource_id})
|
||||
session.commit()
|
||||
|
||||
@@ -8,6 +8,7 @@ import re
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from sqlmodel import Session, select
|
||||
from apps.chat.models.chat_model import Chat
|
||||
from apps.dashboard.models.dashboard_model import CoreDashboard
|
||||
from apps.datasource.crud.datasource import get_ws_ds
|
||||
from apps.datasource.models.datasource import CoreDatasource
|
||||
from common.core.db import engine
|
||||
@@ -27,7 +28,10 @@ async def get_ws_resource(oid, type) -> list:
|
||||
if type == 'ds' or type == 'datasource':
|
||||
return await get_ws_ds(session, oid)
|
||||
if type == 'chat':
|
||||
stmt = select(Chat.id).where(Chat.oid == oid)
|
||||
stmt = select(Chat.id).where(Chat.oid == oid)
|
||||
if type == 'dashboard':
|
||||
# workspace_id 是 VARCHAR 类型,需要转换为字符串
|
||||
stmt = select(CoreDashboard.id).where(CoreDashboard.workspace_id == str(oid))
|
||||
if stmt is not None:
|
||||
db_list = session.exec(stmt).all()
|
||||
return db_list
|
||||
|
||||
Reference in New Issue
Block a user