geo-chen opened a new issue, #41869:
URL: https://github.com/apache/superset/issues/41869

   ### Bug description
   
   ## Timeline
   - 15 June 2026 - reported via email
   - 8 July 2026 - Superset security team requested this be opened as a public 
issue for hardening
   - 8 July 2026 - issue created
   
   I am reporting an SQL injection vulnerability in the Jinja template function 
`latest_sub_partition` available to Presto and Trino database connections in 
SQL Lab.
   
   **Affected versions**: 6.1.0 (confirmed); all versions with Presto/Trino 
support.
   
   **Root cause**: `PrestoBaseEngineSpec.latest_sub_partition` in 
`superset/db_engine_specs/presto.py` contains a broken validation guard at line 
666:
   
   ```python
   for k in kwargs.keys():
       if k not in k in part_fields:  # pylint: disable=comparison-with-itself
           raise SupersetTemplateException(...)
   ```
   
   Python evaluates `k not in k in part_fields` as `(k not in k) and (k in 
part_fields)`. The sub-expression `k not in k` is always `False` for any string 
(a string is always a substring of itself), so the combined expression is 
always `False` and the raise is unreachable. The pylint disable comment 
confirms the linter flagged this; the warning was suppressed rather than fixed.
   
   Caller-supplied kwargs then flow into `_partition_query` (lines 500-501) 
where both the field name and value are interpolated into SQL without escaping:
   
   ```python
   l.append(f"{field} = '{value}'")
   ```
   
   This generates a WHERE clause passed to `database.get_df(sql)` and executed 
against Presto or Trino.
   
   **Entry point**: The function is exposed as `presto.latest_sub_partition` / 
`trino.latest_sub_partition` in the Jinja context for SQL Lab queries when 
`ENABLE_TEMPLATE_PROCESSING=True` is set on the database connection.
   
   **Impact**: When template processing is enabled on a Presto/Trino database, 
any authenticated SQL Lab user can inject SQL into the partition metadata query 
via:
   
   ```sql
   SELECT '{{ presto.latest_sub_partition("schema.table", partition_col="val'' 
UNION SELECT secret FROM other_table--") }}'
   ```
   
   The injected query runs with the database connection's service account 
credentials, which on Hive/Iceberg deployments commonly has read access across 
all schemas. This bypasses Superset row-level security and schema-access 
controls for the affected database.
   
   **PoC (real-fn-in-process, no live Presto required)**:
   
   ```python
   # Verbatim guard from line 666 - always False
   part_fields = ["ds", "event_type"]
   k = "event_type"
   print(k not in k in part_fields)  # False -- guard never fires
   
   # Injection sink from lines 500-501
   filters = {"event_type": "click' UNION SELECT secret FROM vault--"}
   l = []
   for field, value in filters.items():
       l.append(f"{field} = '{value}'")
   where_clause = "WHERE " + " AND ".join(l)
   print(where_clause)
   # Output: WHERE event_type = 'click' UNION SELECT secret FROM vault--'
   ```
   
   **Suggested fix**:
   1. Line 666: change `if k not in k in part_fields:` to `if k not in 
part_fields:`
   2. Lines 500-501: parameterize the query rather than using f-string 
interpolation for filter values.
   
   Both `PrestoEngineSpec` and `TrinoEngineSpec` inherit from 
`PrestoBaseEngineSpec` and are affected.
   
   
   ### Screenshots/recordings
   
   _No response_
   
   ### Superset version
   
   6.1.0
   
   ### Python version
   
   3.9
   
   ### Node version
   
   16
   
   ### Browser
   
   Chrome
   
   ### Additional context
   
   _No response_
   
   ### Checklist
   
   - [x] I have searched Superset docs and Slack and didn't find a solution to 
my problem.
   - [x] I have searched the GitHub issue tracker and didn't find a similar bug 
report.
   - [x] 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