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


##########
superset/mcp_service/auth.py:
##########
@@ -107,14 +116,32 @@ def get_user_from_request() -> User:
     if hasattr(g, "user") and g.user:
         return g.user
 
+    # Try API key authentication via FAB SecurityManager
+    # Only attempt when in a request context (not for MCP internal operations
+    # like tool discovery that run with only an application context)
+    from flask import has_request_context
+
+    api_key_enabled = current_app.config.get("FAB_API_KEY_ENABLED", False)
+    if api_key_enabled and has_request_context():
+        sm = current_app.appbuilder.sm
+        api_key_string = sm._extract_api_key_from_request()
+        if api_key_string is not None:
+            user = sm.validate_api_key(api_key_string)
+            if user:
+                return user

Review Comment:
   **Suggestion:** When authenticating via API key, the user object returned by 
the security manager is used directly without going through the 
`load_user_with_relationships` helper, so nested relationships like 
`Group.roles` may remain lazily loaded and cause detached-instance errors once 
the session is closed or rolled back, which is exactly what the helper is meant 
to prevent. Reload the user via `load_user_with_relationships` after successful 
API key validation so all required relationships are eagerly loaded before MCP 
tools run permission checks. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ MCP tools may crash for API-key-authenticated requests.
   - ❌ Permission checks can fail with DetachedInstanceError.
   - ⚠️ API-key-based MCP automation becomes unreliable under errors.
   - ⚠️ Debugging intermittent auth failures becomes significantly harder.
   ```
   </details>
   
   ```suggestion
                   # Reload user with all relationships eagerly loaded to avoid
                   # detached-instance errors during later permission checks.
                   user_with_relationships = load_user_with_relationships(
                       username=user.username,
                       email=user.email,
                   )
                   return user_with_relationships or user
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. An MCP tool function is decorated with `mcp_auth_hook` defined in
   `superset/mcp_service/auth.py` (see wrapper starting around line 176 in the 
final file).
   
   2. The tool is invoked over HTTP with `Authorization: Bearer sst_...` while
   `FAB_API_KEY_ENABLED` is True and the call is in a Flask request context, so
   `_setup_user_context()` (around line 120) calls `get_user_from_request()` 
(around line
   88).
   
   3. Inside `get_user_from_request()` at lines 124–135, the code executes
   `sm.validate_api_key(api_key_string)` and returns the resulting `user` 
directly, without
   using `load_user_with_relationships()` (defined earlier in the same file) to 
eagerly load
   `roles`, `groups`, and `Group.roles`.
   
   4. Later in the same MCP call, permission logic (e.g. via 
`has_dataset_access()` at line
   152 which uses `security_manager.can_access_datasource(datasource=dataset)` 
and relies on
   `g.user`'s relationships) runs after the SQLAlchemy session has been rolled 
back by
   `_cleanup_session_on_error()` at line 212 or by other Superset DB lifecycle 
code, causing
   a `DetachedInstanceError` when lazy-loading `user.groups` or `group.roles` 
from the user
   obtained via the API key path. The explicit helper 
`load_user_with_relationships()` exists
   to avoid exactly these detached-instance errors, but is currently bypassed 
for
   API-key-authenticated users.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/auth.py
   **Line:** 131:131
   **Comment:**
        *Logic Error: When authenticating via API key, the user object returned 
by the security manager is used directly without going through the 
`load_user_with_relationships` helper, so nested relationships like 
`Group.roles` may remain lazily loaded and cause detached-instance errors once 
the session is closed or rolled back, which is exactly what the helper is meant 
to prevent. Reload the user via `load_user_with_relationships` after successful 
API key validation so all required relationships are eagerly loaded before MCP 
tools run permission checks.
   
   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.
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37973&comment_hash=91be4d49f03aa3ffe4de79a68b5b461f7e422b8bbc035369b0da1ca77adaf72e&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37973&comment_hash=91be4d49f03aa3ffe4de79a68b5b461f7e422b8bbc035369b0da1ca77adaf72e&reaction=dislike'>👎</a>



##########
tests/unit_tests/security/api_test.py:
##########
@@ -29,6 +29,7 @@ def test_csrf_not_exempt(app_context: None) -> None:
     Test that REST API is not exempt from CSRF.
     """
     assert {blueprint.name for blueprint in csrf._exempt_blueprints} == {
+        "ApiKeyApi",

Review Comment:
   **Suggestion:** Adding the API key management blueprint to the CSRF 
exemption list means those endpoints can be called without a CSRF token when 
using cookie-based authentication, which allows cross-site requests to create 
or revoke API keys on behalf of a logged-in user; the API key endpoints should 
not be CSRF-exempt. Update the expected exempt blueprints set to exclude the 
API key API so that configuration and tests enforce CSRF protection for these 
sensitive operations. [security]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ API key creation bypasses CSRF for logged-in users.
   - ❌ API key revocation vulnerable to cross-site request forgery.
   - ⚠️ Admin UI API key management lacks CSRF protection.
   - ⚠️ Security weaker than other protected REST endpoints.
   ```
   </details>
   
   ```suggestion
   
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Run `pytest tests/unit_tests/security/api_test.py::test_csrf_not_exempt`; 
the fixture
   at `tests/unit_tests/security/api_test.py:22-26` creates an app with 
`{"WTF_CSRF_ENABLED":
   True}`.
   
   2. In `test_csrf_not_exempt` at 
`tests/unit_tests/security/api_test.py:31-41`, observe
   that the assertion requires `"ApiKeyApi"` to be present in `{blueprint.name 
for blueprint
   in csrf._exempt_blueprints}`, proving that all routes in the `ApiKeyApi` 
blueprint are
   excluded from CSRF checks.
   
   3. Start the Superset web server with `WTF_CSRF_ENABLED = True` (same 
configuration used
   in the test), then log in through the browser so that a valid session cookie 
is set for
   the Superset domain.
   
   4. From a different origin (e.g., `https://attacker.example`), host an HTML 
page that
   auto-submits a POST form to any state-changing endpoint registered under the 
`ApiKeyApi`
   blueprint (the exact URL can be obtained by inspecting `app.url_map` entries 
for the
   `"ApiKeyApi"` blueprint in a Python shell against the running app); when the 
logged-in
   user visits this page, the browser sends the POST with Superset cookies but 
no CSRF token,
   and because `ApiKeyApi` is listed in `csrf._exempt_blueprints` per step 2, 
the request is
   accepted and the API key create/revoke action succeeds instead of being 
rejected with a
   CSRF error.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** tests/unit_tests/security/api_test.py
   **Line:** 32:32
   **Comment:**
        *Security: Adding the API key management blueprint to the CSRF 
exemption list means those endpoints can be called without a CSRF token when 
using cookie-based authentication, which allows cross-site requests to create 
or revoke API keys on behalf of a logged-in user; the API key endpoints should 
not be CSRF-exempt. Update the expected exempt blueprints set to exclude the 
API key API so that configuration and tests enforce CSRF protection for these 
sensitive operations.
   
   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.
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37973&comment_hash=d9df211586571588dbf7849909735bf2144183b90d02ec4013eb3af5473256c7&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37973&comment_hash=d9df211586571588dbf7849909735bf2144183b90d02ec4013eb3af5473256c7&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