kito-arch commented on issue #32768:
URL: https://github.com/apache/superset/issues/32768#issuecomment-3326947552
> Was any fix for this or workaround ever found that doesn't completely
remove a security check? It is specifically an issue with time grain which sort
of makes embedding significantly less useful.
Workaround for `Time Grain` filter:
```
def query_context_modified(query_context: "QueryContext") -> bool: # noqa:
C901
"""
Check if a query context has been modified.
This is used to ensure guest users don't modify the payload and fetch
data
different from what was shared with them in dashboards.
"""
form_data = query_context.form_data
stored_chart = query_context.slice_
time_grains = [
"PT1S",
"PT5S",
"PT30S",
"PT1M",
"PT5M",
"PT10M",
"PT15M",
"PT30M",
"PT1H",
"P1D",
"P1W",
"P1M",
"P3M",
"P1Y",
]
# native filter requests
if form_data is None or stored_chart is None:
return False
# cannot request a different chart
if form_data.get("slice_id") != stored_chart.id:
return True
stored_query_context: Optional[Dict[str, Any]] = (
json.loads(cast(str, stored_chart.query_context))
if stored_chart.query_context
else None
)
# compare columns and metrics in form_data with stored values
for key, equivalent in [
("metrics", ["metrics"]),
("columns", ["columns", "groupby"]),
("groupby", ["columns", "groupby"]),
("orderby", ["orderby"]),
]:
# basic form / stored param checks (unchanged)
requested_values = {freeze_value(value) for value in
form_data.get(key) or []}
stored_values = {
freeze_value(value) for value in
stored_chart.params_dict.get(key) or []
}
if not requested_values.issubset(stored_values):
return True
queries_non_tg: Set[str] = set()
queries_tg: Set[str] = set()
for query_obj in query_context.queries:
for value in getattr(query_obj, key, []) or []:
if isinstance(value, dict) and "timeGrain" in value:
tg_val = value.get("timeGrain")
if tg_val is not None:
queries_tg.add(tg_val)
value = {k: v for k, v in value.items() if k !=
"timeGrain"}
queries_non_tg.add(freeze_value(value))
stored_non_tg: Set[str] = set()
for value in stored_chart.params_dict.get(key) or []:
if isinstance(value, dict) and "timeGrain" in value:
tg_val = value.get("timeGrain")
value = {k: v for k, v in value.items() if k != "timeGrain"}
stored_non_tg.add(freeze_value(value))
if stored_query_context:
stored_queries = cast(
List[Dict[str, Any]], stored_query_context.get("queries") or
[]
)
for stored_query in stored_queries:
for eq_key in equivalent:
for value in stored_query.get(eq_key) or []:
if isinstance(value, dict) and "timeGrain" in value:
tg_val = value.get("timeGrain")
value = {k: v for k, v in value.items() if k !=
"timeGrain"}
stored_non_tg.add(freeze_value(value))
if not queries_non_tg.issubset(stored_non_tg):
return True
if queries_tg:
allowed_tg = {str(g) for g in time_grains}
if not queries_tg.issubset(allowed_tg):
return True
return False
```
The above code is written with the help of AI.
--
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]