Skip to content

fix(embedded): allow guest users to sort table columns in embedded dashboards#41218

Open
rusackas wants to merge 2 commits into
masterfrom
fix/guest-embedded-table-sort
Open

fix(embedded): allow guest users to sort table columns in embedded dashboards#41218
rusackas wants to merge 2 commits into
masterfrom
fix/guest-embedded-table-sort

Conversation

@rusackas

Copy link
Copy Markdown
Member

SUMMARY

When viewing an embedded dashboard as a guest user, clicking a table column header to sort raises Guest user cannot modify chart payload. This is a false positive from the query_context_modified() guard in superset/security/manager.py.

Root cause: orderby was compared with the same strict subset check as metrics, columns, and groupby — the requested orderby had to be a subset of the stored chart's orderby. Saved charts almost always store orderby == [], so any guest sort (e.g. [["gender", true]]) fails the subset check and the request is rejected, even though sorting only changes the ordering of the result, not which data is read.

Fix: orderby is now validated separately. A guest may sort by any column or metric the stored chart already references (collected from the chart's params_dict and stored query_context — columns, groupby, metrics, all_columns, plus existing order-by targets). Any order-by term not present in the stored chart — e.g. a free-form random() expression — is still rejected, so the existing SQL-injection protection is preserved.

While here, the columns/metrics/groupby comparison is extracted into a small helper (_columns_metrics_modified) to keep query_context_modified within the complexity budget, and a pre-existing variable-shadowing bug in the inner loop (for key in equivalent shadowing the outer key) is fixed.

⚠️ Security-sensitive area — please review carefully. This relaxes the guest payload-tampering guard. The intent is to permit legitimate re-ordering while continuing to reject any order-by term the chart does not already expose. The existing injection test (test_query_context_modified_orderby, sorting by random()) still passes. cc anyone who worked on the recent _native_filter_* hardening in this module — the new check mirrors that _native_filter_term_allowed style.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before: Guest clicks a table column header → Data error: Guest user cannot modify chart payload.
After: Guest can sort embedded table columns. Sorting by an expression not present in the chart (e.g. random()) is still blocked.

TESTING INSTRUCTIONS

pytest tests/unit_tests/security/manager_test.py -k "query_context_modified" -v

New tests (added alongside the existing test_query_context_modified_orderby injection test, which continues to pass):

  • test_query_context_modified_orderby_sort_by_column — sort by an existing column → allowed
  • test_query_context_modified_orderby_sort_by_metric — sort by an existing metric → allowed
  • test_query_context_modified_orderby_sort_by_adhoc_metric — sort by an existing adhoc metric definition → allowed
  • test_query_context_modified_orderby_unknown_column — sort by a column not in the chart → rejected
  • test_query_context_modified_orderby_empty — empty order-by → allowed

Manual: open an embedded dashboard with a table chart as a guest user and click a column header to sort — it should reorder instead of erroring.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

🤖 Generated with Claude Code

query_context_modified() compared a guest request's orderby against the
stored chart's orderby with a strict subset check, alongside columns,
metrics and groupby. Saved charts usually store an empty orderby, so when
a guest clicked a column header to sort a table in an embedded dashboard
the new orderby value failed the subset check and the request was
rejected with "Guest user cannot modify chart payload", even though
sorting only changes result ordering and not which data is read.

Handle orderby separately: a guest may sort by any column or metric the
stored chart already references, but order-by terms that are not present
in the stored chart (e.g. a free-form random() expression) are still
rejected, preserving the existing SQL-injection guard. The columns/
metrics/groupby comparison is extracted into a helper to keep
query_context_modified within the complexity budget, and the inner loop's
variable shadowing of `key` is fixed along the way.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dosubot dosubot Bot added authentication:access-control Rlated to access control embedded viz:charts:table Related to the Table chart labels Jun 19, 2026
@bito-code-review

bito-code-review Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #4f3376

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: 27c481d..27c481d
    • superset/security/manager.py
    • tests/unit_tests/security/manager_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@github-actions github-actions Bot removed the embedded label Jun 19, 2026
Comment thread superset/security/manager.py
Comment thread superset/security/manager.py
@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.10204% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.35%. Comparing base (79cfe4d) to head (7c1fa4a).

Files with missing lines Patch % Lines
superset/security/manager.py 55.10% 15 Missing and 7 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41218      +/-   ##
==========================================
- Coverage   64.36%   64.35%   -0.01%     
==========================================
  Files        2651     2651              
  Lines      144812   144850      +38     
  Branches    33417    33430      +13     
==========================================
+ Hits        93208    93222      +14     
- Misses      49935    49951      +16     
- Partials     1669     1677       +8     
Flag Coverage Δ
hive 39.30% <8.16%> (-0.02%) ⬇️
mysql 58.04% <55.10%> (-0.01%) ⬇️
postgres 58.11% <55.10%> (-0.01%) ⬇️
presto 40.88% <8.16%> (-0.02%) ⬇️
python 59.55% <55.10%> (-0.01%) ⬇️
sqlite 57.77% <55.10%> (-0.01%) ⬇️
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread superset/security/manager.py
Comment thread superset/security/manager.py
…derby in guest sort guard

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bito-code-review

bito-code-review Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #f16dbc

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: 27c481d..7c1fa4a
    • superset/security/manager.py
    • tests/unit_tests/security/manager_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

authentication:access-control Rlated to access control size/L viz:charts:table Related to the Table chart

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants