From fd63503228c7f088379188402712a59aaa548285 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 13:40:46 +0000 Subject: [PATCH] Add permission checks to dataset API Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com> --- .Jules/sentinel.md | 1 + api/dataset_api.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/.Jules/sentinel.md b/.Jules/sentinel.md index 0f720988..75823bcd 100644 --- a/.Jules/sentinel.md +++ b/.Jules/sentinel.md @@ -1,2 +1,3 @@ ## 2026-03-27 - Prevent SQL Error Leakage | Vulnerability: Information Exposure through Error Messages | Learning: Database error traces bubbling up to users can leak schema and path information. | Prevention: Catch database exceptions and return generic error messages (e.g. 500 Internal Server Error) to the client while logging the detailed exception server-side. ## 2026-03-29 - Server-Side Logging of Database Errors | Vulnerability: Insufficient Logging and Monitoring | Learning: Swallowing database errors without logging them hides potential malicious activity like SQL injection attempts. | Prevention: Always log database exception details using `logger.error` on the backend before returning a sanitized generic error to the client. +## 2026-03-31 - Enforce API Scope Authorization | Vulnerability: Missing Authorization | Learning: Endpoints that fetch an authenticated user dependency (`get_current_active_user_or_api_key`) do not automatically enforce permission scopes. | Prevention: Always verify the required `PermissionLevel` (e.g., `READ`, `WRITE`) against the user's or API key's `scopes` before executing the endpoint logic. diff --git a/api/dataset_api.py b/api/dataset_api.py index f7501de2..1363a909 100644 --- a/api/dataset_api.py +++ b/api/dataset_api.py @@ -136,6 +136,9 @@ async def list_datasets( current_auth_entity: Any = Depends(get_current_active_user_or_api_key), ): """List all available datasets (tables in the database).""" + if PermissionLevel.READ not in current_auth_entity["scopes"]: + raise HTTPException(status_code=403, detail="Insufficient permissions to list datasets") + datasets = [] try: conn = get_db_connection() @@ -196,6 +199,9 @@ async def get_dataset_metadata( current_auth_entity: Any = Depends(get_current_active_user_or_api_key), ): """Get metadata (schema) for a specific dataset (table).""" + if PermissionLevel.READ not in current_auth_entity["scopes"]: + raise HTTPException(status_code=403, detail="Insufficient permissions to read dataset metadata") + conn = None try: # Validate input format immediately to prevent any SQL injection attempts @@ -258,6 +264,9 @@ async def query_dataset( """ Query data from a specific dataset (table) with optional filters and pagination. """ + if PermissionLevel.READ not in current_auth_entity["scopes"]: + raise HTTPException(status_code=403, detail="Insufficient permissions to query dataset") + conn = None try: # Validate input format immediately