Skip to content

fix(embedded): compare guest chart payloads against every stored control - #42864

Draft
luizotavio32 wants to merge 1 commit into
apache:6.2from
luizotavio32:fix/embedded-app-62-chart-bug
Draft

fix(embedded): compare guest chart payloads against every stored control#42864
luizotavio32 wants to merge 1 commit into
apache:6.2from
luizotavio32:fix/embedded-app-62-chart-bug

Conversation

@luizotavio32

@luizotavio32 luizotavio32 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

query_context_modified compared a request's metrics, columns, groupby and orderby against identically-named keys in the chart's params. Charts save those values under whichever control names their viz type uses, so a guest merely loading an embedded dashboard was rejected as a tamperer: big number and pie store metric, bubble stores x/y/size, sankey stores source/target, time series stores x_axis.

Each request key is now compared against every equivalent stored control, and orderby against any metric or column the chart already reads — charts sort by their own metric on initial load, with no user interaction. Values are normalized before comparison so the same underlying column compares equal however it is spelled:

  • adhoc references that only point back at a physical column collapse to its name
  • synthesized BASE_AXIS markers (added by normalizeTimeColumn) are shed
  • sort pairs reduce to the expression they sort on
  • scalar-valued controls are no longer iterated character by character

Matching itself stays exact: only the shape of a value is normalized, never its identity, so a collapsed reference still has to match something stored on the chart. Pointing at an unrelated column or wrapping free-form SQL grants no extra access. series_limit_metric and timeseries_limit_metric are included as stored metric controls, so a guest cannot rank top-N groups by arbitrary adhoc SQL.

The comparison helpers move to superset/security/guest_payload.py; freeze_value is re-exported from superset.security.manager for compatibility.

TESTING INSTRUCTIONS

pytest tests/unit_tests/security/manager_test.py — 52 tests, covering per-viz-type control names, each normalization rule, and tamper vectors that must still be rejected.

Manual verification against a real embedded dashboard, which is what this fix is about — synthetic POST /api/v1/chart/data payloads exercise the comparator but not what the frontend actually sends:

  1. Bring up Superset with EMBEDDED_SUPERSET and a guest role, and an embedded dashboard with a spread of viz types.
  2. Load it through the embedded SDK as a guest and confirm every tile renders — before this change, charts whose metrics/columns live under other control names 403 on load.
  3. Confirm the guard is still reachable rather than silently passing: tamper with a payload (add an unsaved metric, or a series_limit_metric with adhoc SQL) and assert a 403 carrying the guard's own message, Guest user cannot modify chart payload. A generic Forbidden means an earlier gate objected and the guard never ran, so a 200 on the legitimate load would prove nothing.

Note that query_context_modified returns early when query_context.slice_ is None. On 6.2 user_view_menu_names() returns nothing for guests, so ChartFilter can hide the slice and the guard no-ops, accepting every payload — step 3 is what distinguishes "allowed" from "never ran".

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

`query_context_modified` compared a request's `metrics`, `columns`, `groupby` and
`orderby` against identically-named keys in the chart's `params`. Charts save those
values under whichever control names their viz type uses, so a guest merely loading
an embedded dashboard was rejected as a tamperer: big number and pie store `metric`,
bubble stores `x`/`y`/`size`, sankey stores `source`/`target`, time series stores
`x_axis`.

Each request key is now compared against every equivalent stored control, and
`orderby` against any metric or column the chart already reads, since charts sort by
their own metric on initial load without user interaction. Values are normalized
before comparison so the same underlying column compares equal however it is spelled
— adhoc references that only point back at a physical column collapse to its name,
synthesized `BASE_AXIS` markers are shed, sort pairs reduce to the expression they
sort on, and scalar-valued controls are no longer iterated character by character.

Matching itself stays exact: only the shape of a value is normalized, never its
identity, so a collapsed reference still has to match something stored on the chart.
Pointing at an unrelated column or wrapping free-form SQL grants no extra access.

The comparison helpers move to `superset/security/guest_payload.py`;
`freeze_value` is re-exported from `superset.security.manager` for compatibility.

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

bito-code-review Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Bito Automatic Review Skipped - Branch Excluded

Bito didn't auto-review because the source or target branch is excluded from automatic reviews.
No action is needed if you didn't intend for the agent to review it. Otherwise, to manually trigger a review, type /review in a comment and save.
You can change the branch exclusion settings here, or contact your Bito workspace admin at evan@preset.io.

@luizotavio32

Copy link
Copy Markdown
Contributor Author

/review

@bito-code-review

bito-code-review Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #4752b5

Actionable Suggestions - 0
Additional Suggestions - 1
  • superset/security/guest_payload.py - 1
    • Import exception consistency · Line 169-169
      Use `json.JSONDecodeError` instead of `ValueError` to catch JSON parsing failures — the module already imports `JSONDecodeError` (line 29) and it is the specific exception type raised by `simplejson.loads` (confirmed in `superset/utils/json.py:29`). Using the base `ValueError` is functionally equivalent but inconsistent with the codebase pattern.
Review Details
  • Files reviewed - 3 · Commit Range: 51c9226..51c9226
    • superset/security/guest_payload.py
    • superset/security/manager.py
    • tests/unit_tests/security/manager_test.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ 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

@netlify

netlify Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 51c9226
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a74f60bebc6470009676783
😎 Deploy Preview https://deploy-preview-42864--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant