CVE-2026-93660 Overview
CVE-2026-93660 is an improper access control vulnerability [CWE-639] in SQLBot through version 1.10.1. The update_resource and update_canvas endpoints fail to verify dashboard ownership before applying changes. Any authenticated workspace member can supply an arbitrary dashboard ID and modify dashboards owned by other users. The flaw allows attackers to rename dashboards and overwrite component data, canvas styles, and view information belonging to other workspace members. The issue is tracked in the dashboard service module of the SQLBot backend and was resolved through a permission enforcement patch on the upstream repository.
Critical Impact
Authenticated workspace members can tamper with the integrity of private dashboards belonging to other users, resulting in unauthorized modification of business intelligence data.
Affected Products
- SQLBot through version 1.10.1
- Backend module backend/apps/dashboard/crud/dashboard_service.py
- Backend module backend/apps/system/schemas/permission.py
Discovery Timeline
- 2026-09-18 - CVE-2026-93660 published to NVD
- 2026-09-22 - Last updated in NVD database
Technical Details for CVE-2026-93660
Vulnerability Analysis
SQLBot exposes REST endpoints for dashboard management including load_resource, update_resource, and update_canvas. These endpoints accept a dashboard identifier as input and mutate the associated record. The service layer functions did not receive the acting current_user context and therefore could not compare the requesting user against the dashboard owner. As a result, the server processed any dashboard ID supplied by any authenticated workspace member. Attackers exploit this behavior to overwrite component definitions, canvas styling, and view metadata belonging to peers in the same workspace. The integrity impact is high while confidentiality and availability remain unaffected.
Root Cause
The vulnerability is a classic Insecure Direct Object Reference (IDOR) tracked as [CWE-639]. The functions in dashboard_service.py operated on the dashboard identifier without an authorization check that binds the resource to its owner. The @require_permissions decorator evaluated coarse-grained workspace permissions, not per-object ownership. Consequently, any user with the dashboard permission scope could act on records outside of their own set.
Attack Vector
An attacker first authenticates as a low-privilege workspace member. They then enumerate or guess numeric dashboard IDs and issue POST requests to /update_resource or /update_canvas with the target ID and attacker-controlled payloads. The server accepts the request and persists the changes to the victim's dashboard.
# Security patch applied in commit fccdd29421dfc32d3a552ab29b2554974e1ebc4c
# File: backend/apps/dashboard/api/dashboard_api.py
@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):
- return load_resource(session=session, dashboard=dashboard)
+ return load_resource(session=session, dashboard=dashboard, current_user=current_user)
@router.post("/create_resource", response_model=BaseDashboard, summary=f"{PLACEHOLDER_PREFIX}create_resource_api")
# File: backend/apps/dashboard/crud/dashboard_service.py
-def load_resource(session: SessionDep, dashboard: QueryDashboard):
+def load_resource(session: SessionDep, dashboard: QueryDashboard, current_user: CurrentUser):
sql = text("""
SELECT cd.*,
creator.name AS create_name,
Source: SQLBot Security Commit fccdd29. The patch threads current_user into the service functions so ownership can be enforced before any dashboard record is loaded or mutated.
Detection Methods for CVE-2026-93660
Indicators of Compromise
- Unexpected changes to dashboard name, component_data, canvas_style, or view_info columns that do not correlate with the owner's session activity.
- HTTP POST requests to /update_resource or /update_canvas from user accounts that do not own the referenced dashboard id.
- Sequential or scripted access to numeric dashboard IDs in application access logs.
Detection Strategies
- Correlate application audit logs of dashboard updates against the recorded dashboard owner to flag mismatches.
- Baseline normal per-user dashboard update volume and alert on outliers that touch many distinct dashboard IDs.
- Review database change-history tables for updates to dashboards not preceded by a matching load_resource call from the same user.
Monitoring Recommendations
- Enable verbose logging on the SQLBot backend dashboard API routes and forward logs to a centralized SIEM.
- Alert on any 4xx or 5xx responses from update endpoints that occur after authentication succeeds, indicating enumeration attempts.
- Track authenticated session activity per workspace and flag lateral access patterns across dashboard resources.
How to Mitigate CVE-2026-93660
Immediate Actions Required
- Upgrade SQLBot to a version that includes commit fccdd29421dfc32d3a552ab29b2554974e1ebc4c or later.
- Audit dashboard records for unauthorized modifications since deployment of version 1.10.1 or earlier.
- Rotate workspace member credentials if unauthorized changes are confirmed.
- Restrict workspace membership to trusted users until the patch is applied.
Patch Information
The upstream fix is available in the SQLBot security commit. The patch propagates the current_user object into load_resource, update, and delete service functions so that per-user ownership can be verified before any state change. Reference the VulnCheck SQLBot Access Control Advisory and GitHub Issue #1377 for additional context.
Workarounds
- Place SQLBot behind a reverse proxy that restricts access to /update_resource and /update_canvas to administrators until patched.
- Reduce shared workspace membership so only trusted operators hold the dashboard permission.
- Enable database-level audit triggers on the dashboard table to capture all modifications with the acting user.
# Example nginx restriction to limit dashboard update endpoints by source IP
location ~ ^/api/dashboard/(update_resource|update_canvas)$ {
allow 10.0.0.0/24; # trusted admin subnet
deny all;
proxy_pass http://sqlbot_backend;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.