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:
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:
Disallowed SQL functions: user
Another generic example is querying MySQL metadata:
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'example_schema'
LIMIT 3;
This can be falsely rejected as:
Disallowed SQL functions: schema
Expected behavior:
Superset should only reject real SQL function calls such as:
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:
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:
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:
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.
Bug description
When using Superset MCP /
Database.execute()with a MySQL-compatible database, the SQL security check forDISALLOWED_SQL_FUNCTIONSappears to match disallowed function names by substring against the full SQL statement.As a result, normal identifiers that contain words such as
userorschemaare falsely rejected, even when they are not function calls.Example sanitized query:
Actual result:
Another generic example is querying MySQL metadata:
This can be falsely rejected as:
Expected behavior:
Superset should only reject real SQL function calls such as:
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:This causes false positives for identifiers such as:
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:
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:usersucceeded.information_schema/table_schemasucceeded.USER()function call was still rejected withDisallowed SQL functions: user.So the issue seems isolated to function detection using substring matching instead of AST function-call detection.
Checklist