Skip to content

fix(embedded): tighten guest-token scoping for annotations, result types, and channels - #43391

Open
rusackas wants to merge 6 commits into
masterfrom
fix/guest-token-embedded-scoping
Open

fix(embedded): tighten guest-token scoping for annotations, result types, and channels#43391
rusackas wants to merge 6 commits into
masterfrom
fix/guest-token-embedded-scoping

Conversation

@rusackas

Copy link
Copy Markdown
Member

SUMMARY

  • Guest-token query tamper checks now also compare annotation_layers and result_type against the stored chart's query context, closing gaps where a request could reference an annotation layer or result type (e.g. samples/drill_detail) the stored chart didn't itself use.
  • The embedded-dashboard pre-auth page no longer renders the dashboard's title/description before a guest token is presented; the SPA fetches that metadata through the authenticated API instead.
  • The guest async-channel id is now derived from the full decoded token claim set instead of an enumerated field subset, so any claim difference (not just the ones someone remembered to list) produces a distinct channel.

TESTING INSTRUCTIONS

pytest tests/unit_tests/security/manager_test.py tests/unit_tests/async_events/ tests/integration_tests/embedded/test_view.py — new/extended tests per change, each verified to fail pre-fix and pass post-fix.

ADDITIONAL INFORMATION

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

Superset Dev added 4 commits August 21, 2026 00:39
query_context_modified() compared columns/metrics/series-limit/order-by
against a chart's stored query context but never inspected
annotation_layers, which is accepted on any query object and resolved by
AnnotationLayerDAO.find_by_ids with no per-object restriction. Add
_annotation_layers_modified(), matching the existing subset-comparator
pattern: the union of annotation layers in form_data and every query
object must already appear (by sourceType/value identity) on the stored
chart's params or saved query_context. Replaying a chart's own layers
still passes; referencing any other layer now fails the guest tamper
check.
query_context_modified() compared columns/metrics/order-by against the
stored chart but never compared result_type, and the samples/drill_detail
preparers in query_actions.py rewrite an accepted query to every column
on the datasource (dropping metrics/post_processing) after that check has
already passed. Add _result_type_modified(), checking the request's
top-level and per-query result_type (samples or drill_detail) against
the stored chart's own saved query context; unless the chart itself uses
one of those result types, requesting it now fails the guest tamper
check.
…t auth

The Referer and Sec-Fetch-Dest checks on the pre-token embed page are
browser-cooperation only; a non-browser client can forge or omit both
headers, so anything the page renders is effectively reachable by
knowing an embed UUID. Stop passing the dashboard title and description
into the template at this stage. The embedded SPA already fetches
dashboard metadata through the guest-token-authenticated API once it
holds a token, so the pre-auth page falls back to a generic title.
get_guest_user_channel_id() HMACed an enumerated subset of guest-token
claims (user/resources/iat/exp/aud/datasets/rev), omitting rls_rules.
Two guest tokens differing only in their RLS clauses -- the documented
pattern for embedding one dashboard across multiple tenants -- could
derive the same async channel and collide on job-status polling and
cancellation. HMAC the complete decoded claim set instead of an
enumerated subset, so any claim difference (including future ones)
yields a distinct channel.
@dosubot dosubot Bot added authentication Related to authentication embedded labels Aug 21, 2026
@bito-code-review

bito-code-review Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #3432a2

Actionable Suggestions - 0
Review Details
  • Files reviewed - 6 · Commit Range: 6f96d11..0893514
    • superset/async_events/async_query_manager.py
    • superset/embedded/view.py
    • superset/security/manager.py
    • tests/integration_tests/embedded/test_view.py
    • tests/unit_tests/async_events/async_query_manager_tests.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 an incremental AI Review.

  • /review full - 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 Aug 21, 2026
Comment thread superset/async_events/async_query_manager.py
@bito-code-review

Copy link
Copy Markdown
Contributor

The flagged issue is correct. Deriving the channel ID from the entire guest token, including iat (issued-at) and exp (expiration), causes the channel identity to change whenever a token is refreshed. This breaks the connection for in-flight async jobs, as the client and server no longer agree on the channel ID.

To resolve this, you should derive the channel ID from a stable claim that persists across token refreshes, such as a unique session identifier or a user-specific claim that remains constant for the duration of the embedded session. You should exclude volatile claims like iat and exp from the channel derivation logic.

I have checked the PR comments, and there are no other actionable suggestions in the provided context. Would you like me to implement a fix for this issue?

superset/async_events/async_query_manager.py

# Use a stable session/channel claim instead of the full token
        message = json.dumps(
            {
                "user": token.get("user"),
                "resources": token.get("resources"),
                "session_id": token.get("session_id"),
            },
            sort_keys=True,
        ).encode("utf-8")

@netlify

netlify Bot commented Aug 21, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit a8284ec
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a88811d09728e0008c743f6
😎 Deploy Preview https://deploy-preview-43391--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.

…ed447e8f5a7bf

# Conflicts:
#	superset/security/manager.py
@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 27.65957% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.78%. Comparing base (a05a099) to head (0ba34c9).
⚠️ Report is 9 commits behind head on master.

Files with missing lines Patch % Lines
superset/security/manager.py 28.26% 28 Missing and 5 partials ⚠️
superset/async_events/async_query_manager.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #43391      +/-   ##
==========================================
- Coverage   66.81%   66.78%   -0.04%     
==========================================
  Files        2876     2876              
  Lines      164237   164451     +214     
  Branches    37917    37956      +39     
==========================================
+ Hits       109743   109828      +85     
- Misses      52310    52424     +114     
- Partials     2184     2199      +15     
Flag Coverage Δ
hive 38.06% <14.89%> (-0.04%) ⬇️
mysql 57.74% <27.65%> (-0.05%) ⬇️
postgres 57.77% <27.65%> (-0.05%) ⬇️
presto 39.99% <14.89%> (-0.04%) ⬇️
python 59.20% <27.65%> (-0.06%) ⬇️
sqlite 57.47% <27.65%> (-0.05%) ⬇️
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.

@rusackas rusackas added the merge-if-green If approved and tests are green, please go ahead and merge it for me label Aug 21, 2026
Comment thread superset/security/manager.py Outdated
…d query, not the flattened set

_result_type_modified previously unioned every stored query's result_type
into one set and checked requested result types against that set, so a
result type stored on one query (e.g. samples) could be requested for a
different query in the same query context. Compare each requested query's
effective result type (its own result_type, falling back to the query
context's top-level result_type - mirroring how the value is resolved at
render time) against the corresponding stored query at the same position
instead.

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

bito-code-review Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #6a5989

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: 0893514..0ba34c9
    • 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 an incremental AI Review.

  • /review full - 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 Related to authentication merge-if-green If approved and tests are green, please go ahead and merge it for me size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants