This is an automated email from the ASF dual-hosted git repository.
eschutho pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 855ca2228cb fix(query_context): raise 422 not 500 on malformed Jinja
in Query datasource access check (#44011)
855ca2228cb is described below
commit 855ca2228cb698c9ceedd7d5001b52d6080ee0f4
Author: Elizabeth Thompson <[email protected]>
AuthorDate: Thu Sep 24 15:02:26 2026 -0700
fix(query_context): raise 422 not 500 on malformed Jinja in Query
datasource access check (#44011)
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
superset/common/query_context_processor.py | 7 +++++-
.../common/test_query_context_processor.py | 28 ++++++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/superset/common/query_context_processor.py
b/superset/common/query_context_processor.py
index eed87377bae..cb4e0694358 100644
--- a/superset/common/query_context_processor.py
+++ b/superset/common/query_context_processor.py
@@ -26,6 +26,7 @@ import pandas as pd
import pyarrow as pa
from flask import current_app
from flask_babel import gettext as _
+from jinja2.exceptions import TemplateError
from pandas.api.types import infer_dtype
from superset.common.chart_data import ChartDataResultFormat
@@ -45,6 +46,7 @@ from superset.daos.chart import ChartDAO
from superset.exceptions import (
QueryObjectValidationError,
SupersetException,
+ SupersetTemplateException,
)
from superset.explorables.base import Explorable
from superset.extensions import cache_manager, security_manager
@@ -937,7 +939,10 @@ class QueryContextProcessor:
# come first to avoid rendering caller-supplied input for a resource
the
# caller is not allowed to access.
if self._qc_datasource.type == DatasourceType.QUERY:
- security_manager.raise_for_access(query=self._qc_datasource)
+ try:
+ security_manager.raise_for_access(query=self._qc_datasource)
+ except TemplateError as ex:
+ raise SupersetTemplateException(str(ex)) from ex
else:
security_manager.raise_for_access(query_context=self._query_context)
diff --git a/tests/unit_tests/common/test_query_context_processor.py
b/tests/unit_tests/common/test_query_context_processor.py
index 117741bb372..b35c51cfe73 100644
--- a/tests/unit_tests/common/test_query_context_processor.py
+++ b/tests/unit_tests/common/test_query_context_processor.py
@@ -2220,6 +2220,34 @@ def
test_raise_for_access_evaluates_access_before_validate():
query.validate.assert_not_called()
+def test_raise_for_access_wraps_template_error_for_query_datasource():
+ """
+ When the datasource is a SQL Lab Query and raise_for_access() Jinja-renders
+ malformed SQL, the raw jinja2 TemplateError must be wrapped in
+ SupersetTemplateException (422) instead of leaking as an unhandled 500.
+ """
+ from jinja2.exceptions import TemplateSyntaxError
+
+ from superset.exceptions import SupersetTemplateException
+ from superset.utils.core import DatasourceType
+
+ query = MagicMock()
+ query_context = MagicMock()
+ query_context.queries = [query]
+ query_context.datasource.type = DatasourceType.QUERY
+
+ processor = QueryContextProcessor(query_context)
+
+ with patch(
+
"superset.common.query_context_processor.security_manager.raise_for_access",
+ side_effect=TemplateSyntaxError("unexpected end of template",
lineno=1),
+ ):
+ with pytest.raises(SupersetTemplateException):
+ processor.raise_for_access()
+
+ query.validate.assert_not_called()
+
+
def test_grouping_sets_fallback_handles_adhoc_and_physical_columns() -> None:
"""
The fallback used on engines without native GROUPING SETS support must