From 588f38bdf16bd9d6a62cebca0a7144e28c9c3de7 Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Tue, 21 Feb 2023 11:01:12 +0100 Subject: [PATCH] fix: Validate jinja rendered query (#22851) (cherry picked from commit c7823e32fffe6ed3cee4fc0d0c1d6b3fc299c80e) --- superset/sqllab/commands/execute.py | 6 ++++- tests/integration_tests/sqllab_tests.py | 32 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/superset/sqllab/commands/execute.py b/superset/sqllab/commands/execute.py index 35a761fab4018..97c8514d5d8d6 100644 --- a/superset/sqllab/commands/execute.py +++ b/superset/sqllab/commands/execute.py @@ -17,6 +17,7 @@ # pylint: disable=too-few-public-methods, too-many-arguments from __future__ import annotations +import copy import logging from typing import Any, Dict, Optional, TYPE_CHECKING @@ -142,9 +143,12 @@ def _run_sql_json_exec_from_scratch(self) -> SqlJsonExecutionStatus: self._save_new_query(query) try: logger.info("Triggering query_id: %i", query.id) - self._validate_access(query) + self._execution_context.set_query(query) rendered_query = self._sql_query_render.render(self._execution_context) + validate_rendered_query = copy.copy(query) + validate_rendered_query.sql = rendered_query + self._validate_access(validate_rendered_query) self._set_query_limit_if_required(rendered_query) self._query_dao.update( query, {"limit": self._execution_context.query.limit} diff --git a/tests/integration_tests/sqllab_tests.py b/tests/integration_tests/sqllab_tests.py index 19e397e8f6961..aa15308e92be1 100644 --- a/tests/integration_tests/sqllab_tests.py +++ b/tests/integration_tests/sqllab_tests.py @@ -736,6 +736,38 @@ def test_sql_json_parameter_error(self): "undefined_parameters": ["stat"], } + @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") + @mock.patch.dict( + "superset.extensions.feature_flag_manager._feature_flags", + {"ENABLE_TEMPLATE_PROCESSING": True}, + clear=True, + ) + def test_sql_json_parameter_authorized(self): + self.login("admin") + + data = self.run_sql( + "SELECT name FROM {{ table }} LIMIT 10", + "3", + template_params=json.dumps({"table": "birth_names"}), + ) + assert data["status"] == "success" + + @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") + @mock.patch.dict( + "superset.extensions.feature_flag_manager._feature_flags", + {"ENABLE_TEMPLATE_PROCESSING": True}, + clear=True, + ) + def test_sql_json_parameter_forbidden(self): + self.login("gamma") + + data = self.run_sql( + "SELECT name FROM {{ table }} LIMIT 10", + "4", + template_params=json.dumps({"table": "birth_names"}), + ) + assert data["errors"][0]["error_type"] == "GENERIC_BACKEND_ERROR" + @mock.patch("superset.sql_lab.get_query") @mock.patch("superset.sql_lab.execute_sql_statement") def test_execute_sql_statements(self, mock_execute_sql_statement, mock_get_query):