luoianun opened a new issue, #42071:
URL: https://github.com/apache/superset/issues/42071

   ### Bug description
   
   When using Superset MCP / `Database.execute()` with a MySQL-compatible 
database, the SQL security check for `DISALLOWED_SQL_FUNCTIONS` appears to 
match disallowed function names by substring against the full SQL statement.
   
   As a result, normal identifiers that contain words such as `user` or 
`schema` are falsely rejected, even when they are not function calls.
   
   Example sanitized query:
   
   ```sql
   SELECT
     event_date,
     SUM(metric_user_count) AS total_users
   FROM some_metrics_table
   WHERE event_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
   GROUP BY event_date
   LIMIT 5;
   ```
   
   Actual result:
   
   ```text
   Disallowed SQL functions: user
   ```
   
   Another generic example is querying MySQL metadata:
   
   ```sql
   SELECT table_name
   FROM information_schema.tables
   WHERE table_schema = 'example_schema'
   LIMIT 3;
   ```
   
   This can be falsely rejected as:
   
   ```text
   Disallowed SQL functions: schema
   ```
   
   Expected behavior:
   
   Superset should only reject real SQL function calls such as:
   
   ```sql
   SELECT USER();
   SELECT SCHEMA();
   ```
   
   It should not reject column names, table names, schema names, or aliases 
that merely contain those substrings.
   
   ### Root cause
   
   In `superset/sql/execution/executor.py`, `_check_disallowed_functions()` 
appears to check each disallowed function with substring matching against the 
statement string:
   
   ```python
   statement_str = str(statement).upper()
   for func in engine_disallowed:
       if func.upper() in statement_str:
           found.add(func)
   ```
   
   This causes false positives for identifiers such as:
   
   ```text
   metric_user_count
   information_schema
   table_schema
   ```
   
   Superset already has AST-based function detection in the SQL parsing layer, 
for example `script.check_functions_present(...)`, which checks actual function 
nodes instead of arbitrary substrings.
   
   ### Suggested fix
   
   Use AST-based function detection instead of substring matching. For example:
   
   ```python
   found = {
       func
       for func in engine_disallowed
       if script.check_functions_present({func})
   }
   ```
   
   This keeps the intended protection for real disallowed function calls, while 
avoiding false positives on identifiers.
   
   ### Environment
   
   Superset version: 6.1.0  
   Python version: 3.10  
   Node version: Not applicable  
   Browser: Not applicable  
   Database engine: MySQL-compatible database  
   Component: Superset MCP SQL execution / `Database.execute()`
   
   ### Additional context
   
   This was observed while using Superset MCP to execute read-only SQL and 
create virtual datasets/charts from a MySQL-compatible database.
   
   A local patch using `script.check_functions_present({func})` fixed the false 
positives:
   
   - Queries with identifiers containing `user` succeeded.
   - Queries with `information_schema` / `table_schema` succeeded.
   - A real `USER()` function call was still rejected with `Disallowed SQL 
functions: user`.
   
   So the issue seems isolated to function detection using substring matching 
instead of AST function-call detection.
   
   ### Checklist
   
   - I have searched Superset docs and Slack and didn't find a solution to my 
problem.
   - I have searched the GitHub issue tracker and didn't find a similar bug 
report.
   - I have checked Superset's logs for errors and if I found a relevant Python 
stacktrace, I included it here as text in the "additional context" section.
   


-- 
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