codeant-ai-for-open-source[bot] commented on code in PR #41753:
URL: https://github.com/apache/superset/pull/41753#discussion_r3537762382


##########
superset/mcp_service/chart/tool/get_chart_data.py:
##########
@@ -604,6 +623,11 @@ async def get_chart_data(  # noqa: C901
                 )
             )
 
+            # For an embedded guest, attach the dashboard context so
+            # raise_for_access authorizes the data query.
+            if guest_dashboard_id is not None:
+                guest_scope.authorize_query(query_context, guest_dashboard_id, 
chart)

Review Comment:
   **Suggestion:** The guest path currently fails open when embedded-dashboard 
scope cannot be resolved: dataset RBAC pre-check is skipped for every guest, 
and query authorization is only injected when `guest_dashboard_id` is present. 
If a guest request reaches this point with `guest_dashboard_id` missing, the 
query can run without the embedded dashboard guard and rely only on generic 
datasource permissions. Treat “guest with no resolved dashboard scope” as an 
access error and only skip dataset pre-check when the guest scope is actually 
resolved. [security]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   ❌ Embedded guest assistant may read data beyond token dashboards.
   ⚠️ Dataset RBAC bypassed when guest scope resolution fails.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Start Superset with embedded MCP tools enabled and configure a guest user 
whose
   security profile allows datasource access (via `get_dataset_access_filters` 
in
   `superset/utils/filters.py:24-43`) but whose guest token has no DASHBOARD 
resources, so
   `guest_embedded_dashboard_filter()` in `superset/utils/filters.py:46-83` 
returns `None`.
   
   2. As that guest user, resolve a chart directly by identifier through
   `ChartDAO.find_by_id()` at `superset/daos/chart.py:349-381`; because
   `guest_embedded_dashboard_filter()` returned `None`, `ChartFilter.apply()` at
   `superset/charts/filters.py:107-137` falls back to dataset-based filters and 
allows the
   chart through based solely on datasource permissions.
   
   3. From the same embedded guest context, invoke the MCP tool 
`get_chart_data` (`async def
   get_chart_data` in 
`superset/mcp_service/chart/tool/get_chart_data.py:288-307`) with the
   chart’s numeric ID; inside the function, `guest_scope.is_guest_read()`
   (`superset/mcp_service/guest_scope.py:35-41`) returns `True`, so the dataset 
RBAC
   pre-check block at 
`superset/mcp_service/chart/tool/get_chart_data.py:414-430` is entirely
   skipped for this guest.
   
   4. Still in `get_chart_data`, `guest_dashboard_id = 
guest_scope.guest_dashboard_id(chart)`
   at `superset/mcp_service/chart/tool/get_chart_data.py:391` returns `None` 
because the
   chart is not on any guest-authorized dashboard 
(`guest_scope.guest_dashboard_id` in
   `superset/mcp_service/guest_scope.py:44-54` finds no `has_guest_access` 
matches), so the
   authorization injection at 
`superset/mcp_service/chart/tool/get_chart_data.py:626-629`
   never runs; `ChartDataCommand.run()` executes the query without embedded 
dashboard context
   and without prior dataset validation, meaning the guest can read chart data 
purely based
   on generic datasource permissions instead of the intended embedded-dashboard 
scope.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=2a2dc6ee2c3e45bfb065db0a724f3250&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=2a2dc6ee2c3e45bfb065db0a724f3250&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/chart/tool/get_chart_data.py
   **Line:** 415:629
   **Comment:**
        *Security: The guest path currently fails open when embedded-dashboard 
scope cannot be resolved: dataset RBAC pre-check is skipped for every guest, 
and query authorization is only injected when `guest_dashboard_id` is present. 
If a guest request reaches this point with `guest_dashboard_id` missing, the 
query can run without the embedded dashboard guard and rely only on generic 
datasource permissions. Treat “guest with no resolved dashboard scope” as an 
access error and only skip dataset pre-check when the guest scope is actually 
resolved.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41753&comment_hash=7e95e0360462b42f91f0739445130ff15f9d1a731fe5b947a4e55e3f8ecde801&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41753&comment_hash=7e95e0360462b42f91f0739445130ff15f9d1a731fe5b947a4e55e3f8ecde801&reaction=dislike'>👎</a>



##########
superset/mcp_service/chart/tool/get_chart_info.py:
##########
@@ -106,9 +106,13 @@ async def _validate_chart_dataset_access(
     Logs any non-fatal warnings (e.g., virtual dataset warnings) via ctx.
     """
     from superset.daos.chart import ChartDAO
+    from superset.mcp_service import guest_scope
 
     if not result.id:
         return None
+    # Guests read via the dashboard context, not dataset RBAC; skip the 
perm-check.
+    if guest_scope.is_guest_read():
+        return None

Review Comment:
   **Suggestion:** Skipping dataset access validation for all guests is too 
broad because it does not verify that the request is actually bound to a 
guest-authorized embedded dashboard context. This creates a contract gap where 
guest requests with incomplete/invalid dashboard scoping can still return chart 
info. Gate this skip on a successfully resolved guest dashboard scope (or 
reject when guest scope cannot be resolved) instead of on `is_guest_read()` 
alone. [security]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   ❌ Embedded guest chart-info tool exposes metadata beyond dashboards.
   ⚠️ Guest metadata access not tied to embedded dashboard scope.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Configure an embedded guest user in Superset whose guest token has either 
no DASHBOARD
   resources or resources that do not include the target chart’s dashboards, so
   `guest_embedded_dashboard_filter()` in `superset/utils/filters.py:46-83` 
returns `None`
   and `ChartFilter.apply()` in `superset/charts/filters.py:107-137` falls back 
to dataset
   access filters rather than dashboard scoping.
   
   2. Grant this guest user datasource-level access such that 
`get_dataset_access_filters()`
   (`superset/utils/filters.py:24-43`) returns a filter matching the chart’s 
datasource; then
   call `ChartDAO.find_by_id()` from MCP via `ChartInfo` resolution (used in
   `ModelGetInfoCore` in `superset/mcp_service/mcp_core.py`, and invoked in 
`get_chart_info`
   at `superset/mcp_service/chart/tool/get_chart_info.py:319-331`), allowing 
the chart to be
   resolved based on datasource permissions alone.
   
   3. From the embedded guest context, invoke the MCP tool `get_chart_info` 
(`async def
   get_chart_info` in 
`superset/mcp_service/chart/tool/get_chart_info.py:234-280`) with the
   chart’s identifier so that `ModelGetInfoCore.run_tool()` returns a 
`ChartInfo` object
   describing that chart.
   
   4. After chart resolution, `_validate_chart_dataset_access()` is called at
   `superset/mcp_service/chart/tool/get_chart_info.py:353-356`; inside this 
helper
   (`superset/mcp_service/chart/tool/get_chart_info.py:100-130`),
   `guest_scope.is_guest_read()` (`superset/mcp_service/guest_scope.py:35-41`) 
returns `True`
   and the function immediately returns `None`, skipping the dataset access 
validation
   entirely, so the guest receives full chart metadata (including datasource 
name/type) even
   though the request is not proven to be bound to any guest-authorized 
dashboard context.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=2e2f54e9e2bf4f2fad183a15b78f89c4&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=2e2f54e9e2bf4f2fad183a15b78f89c4&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/chart/tool/get_chart_info.py
   **Line:** 114:115
   **Comment:**
        *Security: Skipping dataset access validation for all guests is too 
broad because it does not verify that the request is actually bound to a 
guest-authorized embedded dashboard context. This creates a contract gap where 
guest requests with incomplete/invalid dashboard scoping can still return chart 
info. Gate this skip on a successfully resolved guest dashboard scope (or 
reject when guest scope cannot be resolved) instead of on `is_guest_read()` 
alone.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41753&comment_hash=e9352c6da8a1c84ad2263c9a8ce372224d3a7a8f02fd6759cacd5904e3c70673&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41753&comment_hash=e9352c6da8a1c84ad2263c9a8ce372224d3a7a8f02fd6759cacd5904e3c70673&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to