fix: Validate jinja rendered query (#22851)

This commit is contained in:
Geido 2023-02-21 11:01:12 +01:00 committed by GitHub
parent 5482f78a9c
commit c7823e32ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 1 deletions

View File

@ -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 @@ class ExecuteSqlCommand(BaseCommand):
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}

View File

@ -736,6 +736,38 @@ class TestSqlLab(SupersetTestCase):
"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):