rusackas opened a new pull request, #41217:
URL: https://github.com/apache/superset/pull/41217

   ### SUMMARY
   
   `RlsRuleSchema` (used to validate the `rls` rules in `POST 
/api/v1/security/guest_token/`) inherits from `PermissiveSchema`, whose 
`Meta.unknown = EXCLUDE` silently drops any field it doesn't recognize. So a 
guest-token RLS rule that uses a mistyped or legacy scope key — most commonly 
`datasource: { id, type }` (a leftover from older payloads) instead of the 
documented `dataset: <int>` — has that key stripped during deserialization. The 
resulting rule has no `dataset`.
   
   `SecurityManager.get_guest_rls_filters()` treats a rule with no `dataset` as 
**global** (`if not rule.get("dataset")`, `superset/security/manager.py`), so 
the clause ends up applied to *every* dataset the embedded resource can reach 
instead of the single dataset the caller intended. The visible symptom is 
confusing query errors (e.g. `column "…" does not exist` when the clause lands 
on an unrelated dataset), and the rule's effective scope silently differs from 
what the integrator configured.
   
   This makes `RlsRuleSchema` strict (`Meta.unknown = RAISE`) so an unexpected 
field raises a `ValidationError` (HTTP 400) that names the offending field, 
*before* a token is ever issued — instead of quietly producing a global rule. 
This:
   
   - Aligns runtime validation with the documented `RlsRule` contract (the 
OpenAPI spec advertises only `dataset` and `clause`).
   - Surfaces caller mistakes immediately rather than at query time on an 
unrelated dataset.
   - Leaves valid rules untouched — both dataset-scoped (`{"dataset": 41, 
"clause": "…"}`) and intentionally global (`{"clause": "…"}`) rules still load.
   - Keeps the rest of the guest-token payload (`GuestTokenCreateSchema`, 
`UserSchema`, `ResourceSchema`) permissive, so integrator-specific extra fields 
elsewhere are unaffected.
   
   Framed as input-validation hardening / DX, not a privilege-escalation fix: 
the `guest_token` endpoint is called by a trusted integrator holding 
`can_grant_guest_token`, and RLS clauses are additive restrictions — so the 
impact is incorrect/over-broad rule scoping and confusing errors, not a 
Superset access-control bypass.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   N/A — API-only change.
   
   ### TESTING INSTRUCTIONS
   
   Unit tests added in `tests/unit_tests/security/api_test.py`:
   
   - `test_rls_rule_schema_accepts_dataset_scoped_rule` — `{"dataset": 41, 
"clause": "…"}` still loads.
   - `test_rls_rule_schema_accepts_global_rule` — `{"clause": "…"}` (no 
`dataset`) still loads.
   - `test_rls_rule_schema_rejects_unknown_scope_key` — `{"datasource": {…}, 
"clause": "…"}` now raises `ValidationError` naming `datasource`.
   - `test_rls_rule_schema_rejects_unknown_fields` — any other unknown field is 
rejected.
   - `test_rls_rule_schema_requires_clause` — `clause` remains required.
   
   ```bash
   pytest tests/unit_tests/security/api_test.py -v
   ```
   
   Manual: `POST /api/v1/security/guest_token/` with an `rls` entry using 
`datasource` instead of `dataset` now returns HTTP 400 pointing at the 
`datasource` field, instead of issuing a token whose rule is silently global.
   
   ### ADDITIONAL INFORMATION
   
   This tightens an API contract: integrators that were sending extra fields 
inside RLS rules (previously dropped) will now get a 400. Documented in 
`UPDATING.md`.
   
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] 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
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
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]

Reply via email to