From f10a296ed028b528d22b9176007d7c822918eb31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 13:23:28 -0700 Subject: [PATCH 01/10] chore(deps): bump nh3 from 0.2.21 to 0.3.5 (#40551) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evan Co-authored-by: Claude Sonnet 4.6 --- pyproject.toml | 2 +- requirements/base.txt | 2 +- requirements/development.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7a91bffa5099..c7533a62e2c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,7 +71,7 @@ dependencies = [ "marshmallow>=3.0, <4", "marshmallow-union>=0.1", "msgpack>=1.0.0, <1.2", - "nh3>=0.2.11, <0.4", + "nh3>=0.3.5, <0.4", "numpy>1.23.5, <2.3", "packaging", # -------------------------- diff --git a/requirements/base.txt b/requirements/base.txt index 179176a223cc..68dddfa79d97 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -241,7 +241,7 @@ msgpack==1.0.8 # via apache-superset (pyproject.toml) msgspec==0.19.0 # via flask-session -nh3==0.2.21 +nh3==0.3.5 # via apache-superset (pyproject.toml) numexpr==2.10.2 # via -r requirements/base.in diff --git a/requirements/development.txt b/requirements/development.txt index bb2e963453f6..90d4d920e22e 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -566,7 +566,7 @@ msgspec==0.19.0 # flask-session mysqlclient==2.2.6 # via apache-superset -nh3==0.2.21 +nh3==0.3.5 # via # -c requirements/base-constraint.txt # apache-superset From dfa4dbb96c8b85f2c2880115e45b4ea0cb49cc37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 13:24:00 -0700 Subject: [PATCH 02/10] chore(deps-dev): update denodo-sqlalchemy requirement from <2.1.0,>=1.0.6 to >=2.0.5,<2.1.0 (#40550) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c7533a62e2c5..abd355f1c5ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -135,7 +135,7 @@ databricks = [ "databricks-sqlalchemy==1.0.5", ] db2 = ["ibm-db-sa>0.3.8, <=0.4.4"] -denodo = ["denodo-sqlalchemy>=1.0.6,<2.1.0"] +denodo = ["denodo-sqlalchemy>=2.0.5,<2.1.0"] dremio = ["sqlalchemy-dremio>=1.2.1, <4"] drill = ["sqlalchemy-drill>=1.1.10, <2"] druid = ["pydruid>=0.6.5,<0.7"] From ab66f0066ada2be1dffbc2a3515c49651d5fbe22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 13:24:21 -0700 Subject: [PATCH 03/10] chore(deps-dev): update sqlalchemy-cratedb requirement from <1,>=0.40.1 to >=0.41.0,<1 (#40549) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index abd355f1c5ee..37e07db0e8c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -123,7 +123,7 @@ bigquery = [ ] clickhouse = ["clickhouse-connect>=0.13.0, <2.0"] cockroachdb = ["cockroachdb>=0.3.5, <0.4"] -crate = ["sqlalchemy-cratedb>=0.40.1, <1"] +crate = ["sqlalchemy-cratedb>=0.41.0, <1"] d1 = [ "superset-engine-d1>=0.1.0", "sqlalchemy-d1>=0.1.0", From 35125d85215ffd029334f1519239fa71cda2ddb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 13:24:38 -0700 Subject: [PATCH 04/10] chore(deps-dev): bump syntaqlite from 0.1.0 to 0.5.9 (#40548) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evan Co-authored-by: Claude Sonnet 4.6 --- pyproject.toml | 4 ++-- requirements/development.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 37e07db0e8c6..92dca6a5fdd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -190,7 +190,7 @@ risingwave = ["sqlalchemy-risingwave"] shillelagh = ["shillelagh[all]>=1.4.4, <2"] singlestore = ["sqlalchemy-singlestoredb>=1.1.1, <2"] snowflake = ["snowflake-sqlalchemy>=1.2.4, <2"] -sqlite = ["syntaqlite>=0.1.0"] +sqlite = ["syntaqlite>=0.1.0,<0.5.0"] spark = [ "pyhive[hive]>=0.6.5;python_version<'3.11'", "pyhive[hive_pure_sasl]>=0.7", @@ -235,7 +235,7 @@ development = [ "ruff", "sqloxide", "statsd", - "syntaqlite>=0.1.0", + "syntaqlite>=0.4.2,<0.5.0", ] [project.urls] diff --git a/requirements/development.txt b/requirements/development.txt index 90d4d920e22e..99d0839267ec 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -1005,7 +1005,7 @@ starlette==0.49.1 # via mcp statsd==4.0.1 # via apache-superset -syntaqlite==0.1.0 +syntaqlite==0.4.2 # via apache-superset tabulate==0.10.0 # via From afc4f3c9b3f08194756ad74aec4353ead68771c9 Mon Sep 17 00:00:00 2001 From: Shaitan <105581038+sha174n@users.noreply.github.com> Date: Sat, 30 May 2026 21:26:38 +0100 Subject: [PATCH 05/10] fix(database): extend URI blocklist to cover duckdb dialect (#40402) Co-authored-by: Claude Opus 4.7 --- superset/security/analytics_db_safety.py | 4 ++++ .../security/analytics_db_safety_tests.py | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/superset/security/analytics_db_safety.py b/superset/security/analytics_db_safety.py index 9af12d9b7773..6266391ba8a2 100644 --- a/superset/security/analytics_db_safety.py +++ b/superset/security/analytics_db_safety.py @@ -30,6 +30,10 @@ re.compile(r"sqlite(?:\+[^\s]*)?$"), # shillelagh allows opening local files (eg, 'SELECT * FROM "csv:///etc/passwd"') re.compile(r"shillelagh(?:\+[^\s]*)?$"), + # duckdb exposes filesystem table-valued functions (read_csv_auto, read_text, + # read_parquet, glob, etc.) that grant arbitrary local file access. The + # motherduck cloud variant rides on the same dialect and is covered too. + re.compile(r"duckdb(?:\+[^\s]*)?$"), } diff --git a/tests/integration_tests/security/analytics_db_safety_tests.py b/tests/integration_tests/security/analytics_db_safety_tests.py index 70f9104e3e7a..2c1c5f2d48a4 100644 --- a/tests/integration_tests/security/analytics_db_safety_tests.py +++ b/tests/integration_tests/security/analytics_db_safety_tests.py @@ -97,6 +97,26 @@ True, "shillelagh cannot be used as a data source for security reasons.", ), + ( + "duckdb:///:memory:", + True, + "duckdb cannot be used as a data source for security reasons.", + ), + ( + "duckdb:////tmp/local.db", + True, + "duckdb cannot be used as a data source for security reasons.", + ), + ( + "duckdb+duckdb_engine:////tmp/local.db", + True, + "duckdb cannot be used as a data source for security reasons.", + ), + ( + "duckdb:///md:my_db?motherduck_token=tok", + True, + "duckdb cannot be used as a data source for security reasons.", + ), ], ) def test_check_sqlalchemy_uri( From 8e47eb1cc19a96211be9c739f85defb0adde478b Mon Sep 17 00:00:00 2001 From: Shaitan <105581038+sha174n@users.noreply.github.com> Date: Sat, 30 May 2026 21:27:00 +0100 Subject: [PATCH 06/10] docs(security): explicit security model, role/capability matrix, AGENTS.md linkage (#40503) Co-authored-by: Claude Opus 4.7 --- .github/SECURITY.md | 75 ----------------------- AGENTS.md | 38 ++++++++++++ SECURITY.md | 145 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 75 deletions(-) delete mode 100644 .github/SECURITY.md create mode 100644 SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md deleted file mode 100644 index 79ae21ed4d4d..000000000000 --- a/.github/SECURITY.md +++ /dev/null @@ -1,75 +0,0 @@ -# Security Policy - -This is a project of the [Apache Software Foundation](https://apache.org) and follows the -ASF [vulnerability handling process](https://apache.org/security/#vulnerability-handling). - -## Reporting Vulnerabilities - -**⚠️ Please do not file GitHub issues for security vulnerabilities as they are public! ⚠️** - - -Apache Software Foundation takes a rigorous standpoint in annihilating the security issues -in its software projects. Apache Superset is highly sensitive and forthcoming to issues -pertaining to its features and functionality. -If you have any concern or believe you have found a vulnerability in Apache Superset, -please get in touch with the Apache Superset Security Team privately at -e-mail address [security@superset.apache.org](mailto:security@superset.apache.org). - -More details can be found on the ASF website at -[ASF vulnerability reporting process](https://apache.org/security/#reporting-a-vulnerability) - -**Submission Standards & AI Policy** - -To ensure engineering focus remains on verified risks and to manage high reporting volumes, all reports must meet the following criteria: -- Plain Text Format: In accordance with Apache guidelines, please provide all details in plain text within the email body. Avoid sending PDFs, Word documents, or password-protected archives. -- Mandatory AI Disclosure: If you utilized Large Language Models (LLMs) or AI tools to identify a flaw or assist in writing a report, you must disclose this in your submission so our triage team can contextualize the findings. -- Human-Verified PoC: All submissions must include a manual, step-by-step Proof of Concept (PoC) performed on a supported release. Raw AI outputs, hypothetical chat transcripts, or unverified scanner logs will be closed as Invalid. - -We kindly ask you to include the following information in your report to assist our developers in triaging and remediating issues efficiently: -- Version/Commit: The specific version of Apache Superset or the Git commit hash you are using. -- Configuration: A sanitized copy of your `superset_config.py` file or any config overrides. -- Environment: Your deployment method (e.g., Docker Compose, Helm, or source) and relevant OS/Browser details. -- Impacted Component: Identification of the affected area (e.g., Python backend, React frontend, or a specific database connector). -- Expected vs. Actual Behavior: A clear description of the intended system behavior versus the observed vulnerability. -- Detailed Reproduction Steps: Clear, manual steps to reproduce the vulnerability. - -**Vulnerability Definition** - -Apache Superset considers a security vulnerability to be a demonstrable issue that has meaningful impact on confidentiality, integrity, or availability beyond the intended security model. Low-impact boundary variations or technical edge cases in existing access controls may be classified as hardening improvements rather than vulnerabilities, even if exploitable. - -**Out of Scope Vulnerabilities** - -To prioritize engineering efforts on genuine architectural risks, the following scenarios are explicitly out of scope and will not be issued a CVE: -- **Attacks requiring Admin privileges**: (e.g., CSS injection, template manipulation, dashboard ownership overrides, or modifying global system settings). Per the CVE vulnerability definition in CNA Operational Rules 4.1, a qualifying vulnerability must allow violation of a security policy. The Admin role is a fully trusted operational boundary defined by Apache Superset's security policy; actions within this boundary do not violate that policy and are therefore considered intended capabilities 'by design,' not vulnerabilities. -- **Brute Force and Rate Limiting**: Reports targeting a lack of resource exhaustion protections, generic rate-limiting, or volumetric Denial of Service (DoS) attempts. -- **Theoretical attack vectors**: Issues without a demonstrable, reproducible exploit path. -- **Non-Exploitable Findings**: Missing security headers, generic banner disclosures, or descriptive error messages that do not lead to a direct, documented exploit. -- **User enumeration**: API responses, timing differences, or error messages that reveal whether user accounts, IDs, dashboards, or datasets exist. -- **Information disclosure (low impact)**: Software version disclosure, generic error messages, stack traces without sensitive data exposure, or system configuration details that don't enable further exploitation. -- **Resource exhaustion requiring authentication**: Denial of Service attacks that require valid user credentials and don't bypass rate limiting or resource controls. -- **Missing security headers**: Without demonstration of a concrete exploit scenario that leverages the missing header. - -**Outcome of Reports** - -Reports that are deemed out-of-scope for a CVE but represent valid security best practices or hardening opportunities may be converted into public GitHub issues. This allows the community to contribute to the general hardening of the platform even when a specific vulnerability threshold is not met. - -Note that Apache Superset is not responsible for any third-party dependencies that may -have security issues. Any vulnerabilities found in third-party dependencies should be -reported to the maintainers of those projects. Results from security scans of Apache -Superset dependencies found on its official Docker image can be remediated at release time -by extending the image itself. - -**Vulnerability Aggregation & CVE Attribution** - -In accordance with MITRE CNA Operational Rules (4.1.10, 4.1.11, and 4.2.13), Apache Superset issues CVEs based on the underlying architectural root cause rather than the number of affected endpoints or exploit payloads. -- Aggregation: If multiple exploit vectors stem from the same programmatic failure or shared vulnerable code, they must be aggregated into a single, comprehensive report. -- Independent Fixes: Separate CVEs will only be assigned if the vulnerabilities reside in decoupled architectural modules and can be fixed independently of one another. -Reports that fail to aggregate related findings will be merged during triage to ensure an accurate and defensible CVE record. - -**Your responsible disclosure and collaboration are invaluable.** - -## Extra Information - - - [Apache Superset documentation](https://superset.apache.org/docs/security) - - [Common Vulnerabilities and Exposures by release](https://superset.apache.org/docs/security/cves) - - [How Security Vulnerabilities are Reported & Handled in Apache Superset (Blog)](https://preset.io/blog/how-security-vulnerabilities-are-reported-and-handled-in-apache-superset/) diff --git a/AGENTS.md b/AGENTS.md index 16f085e4e86f..e3d45185eea0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -52,6 +52,43 @@ Common pre-commit failures: - **External API exposure** - Use UUIDs in public APIs instead of internal integer IDs - **Existing models** - Add UUID fields alongside integer IDs for gradual migration +## Security and Threat Model + +Before evaluating any code path for security issues, read [`SECURITY.md`](SECURITY.md). It is the canonical, authoritative source for Apache Superset's security model and is referenced by both human reporters and automated scanners. + +In short, the test for whether a finding is in scope is one question: + +> *Does it let a principal perform an action the role and capability matrix in `SECURITY.md` does not entitle them to?* + +If yes, it is in scope. If no, it is not. + +The three trust boundaries are: + +1. **The Admin role** is a fully trusted operational principal. Anything an Admin can do through documented configuration, API, or UI is an intended capability, not a vulnerability. +2. **The operator** owns deployment-time decisions (secrets, network exposure, feature-flag selection, connector and codec choices, notification destinations, third-party plugins). Misconfiguration at this layer is a deployment defect, not a Superset vulnerability. +3. **The codebase** is responsible for enforcing the role and capability matrix wherever it exposes functionality to a principal: API routes, command and DAO layers, UI handlers, background jobs, and any other entry point. A missing or incorrect enforcement check is in scope no matter where it lives. + +The security model assumes that operator-controlled infrastructure, including the metadata database, cache backends, message brokers, secret stores, and deployment environment, remains within the operator's trust boundary. Vulnerabilities must demonstrate a security boundary violation by an attacker who does not already control those systems. + +Route-level authorization in this codebase uses one of three Flask-AppBuilder decorators depending on the route type: + +- `@protect()` for REST API routes (`ModelRestApi` / `BaseApi`) +- `@has_access_api` for legacy view routes +- `@has_access` for legacy HTML view routes + +Object-level authorization via `security_manager.raise_for_access(...)` applies to data-bearing resources: dashboards, charts, datasets and datasources, queries, database and table access, and query contexts. Other resources (annotations, tags, CSS templates, reports, RLS rules, and similar) rely on the route-level decorator plus DAO `base_filters` for ownership scoping; the absence of `raise_for_access` on these resources is by design, not a finding. Code that omits the per-object gate on a route that returns or mutates a specific data-bearing object is in scope; code that follows the correct pattern for its resource class can still contain injection, SSRF, XSS, or other classes of finding unrelated to authorization, which are evaluated separately. + +The full role and capability matrix, in-scope and out-of-scope class lists, and CVE aggregation rules are in [`SECURITY.md`](SECURITY.md). Defer to that document for any specifics. + +**Requirements for findings filed by automated tooling** + +Automated scanners (LLM-based code scanners, static analyzers, dependency tools) that file findings against this codebase must, in each finding, name: + +1. The specific role and capability matrix row in [`SECURITY.md`](SECURITY.md) the finding believes is violated. +2. The principal the finding assumes the attacker holds (Public, Gamma, sql_lab, Alpha, Admin, Embedded guest token, or a custom role with explicit capability grants). + +Findings that cannot identify both should be filed as questions, not vulnerabilities. This requirement exists to ensure every reported issue is testable against the published security model and to keep speculative or pattern-match-only reports out of the triage queue. + ## Key Directories ``` @@ -128,6 +165,7 @@ The Developer Portal auto-generates MDX documentation from Storybook stories. ** ## Architecture Patterns ### Security & Features +- **Security model**: see the top-level [Security and Threat Model](#security-and-threat-model) section and [`SECURITY.md`](SECURITY.md) - **RBAC**: Role-based access via Flask-AppBuilder - **Feature flags**: Control feature rollouts - **Row-level security**: SQL-based data access control diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000000..e8ecfe56aec2 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,145 @@ + + +# Security Policy + +This is a project of the [Apache Software Foundation](https://apache.org) and follows the +ASF [vulnerability handling process](https://apache.org/security/#vulnerability-handling). + +## Reporting Vulnerabilities + +**⚠️ Please do not file GitHub issues for security vulnerabilities as they are public! ⚠️** + + +Apache Software Foundation takes a rigorous standpoint in resolving the security issues +in its software projects. Apache Superset is highly sensitive and forthcoming to issues +pertaining to its features and functionality. +If you have any concern or believe you have found a vulnerability in Apache Superset, +please get in touch with the Apache Superset Security Team privately at +e-mail address [security@superset.apache.org](mailto:security@superset.apache.org). + +More details can be found on the ASF website at +[ASF vulnerability reporting process](https://apache.org/security/#reporting-a-vulnerability) + +**Submission Standards & AI Policy** + +To ensure engineering focus remains on verified risks and to manage high reporting volumes, all reports must meet the following criteria: +- Plain Text Format: In accordance with Apache guidelines, please provide all details in plain text within the email body. Avoid sending PDFs, Word documents, or password-protected archives. +- Mandatory AI Disclosure: If you utilized Large Language Models (LLMs) or AI tools to identify a flaw or assist in writing a report, you must disclose this in your submission so our triage team can contextualize the findings. +- Human-Verified PoC: All submissions must include a manual, step-by-step Proof of Concept (PoC) performed on a supported release. Raw AI outputs, hypothetical chat transcripts, or unverified scanner logs will be closed as Invalid. + +We kindly ask you to include the following information in your report to assist our developers in triaging and remediating issues efficiently: +- Version/Commit: The specific version of Apache Superset or the Git commit hash you are using. +- Configuration: A sanitized copy of your `superset_config.py` file or any config overrides. +- Environment: Your deployment method (e.g., Docker Compose, Helm, or source) and relevant OS/Browser details. +- Impacted Component: Identification of the affected area (e.g., Python backend, React frontend, or a specific database connector). +- Expected vs. Actual Behavior: A clear description of the intended system behavior versus the observed vulnerability. +- Detailed Reproduction Steps: Clear, manual steps to reproduce the vulnerability. + +## Security Model + +This section defines what Apache Superset considers a security issue and what it does not. It is the canonical reference for reporters, the Apache Superset Security Team, and any automated tool (LLM-based scanner, static analyzer, dependency tool) that needs to constrain its hypotheses to behaviors that genuinely violate the project's security policy. + +The model is intentionally written in terms of principals, trust boundaries, and capability surface rather than in terms of specific files, functions, or libraries. New code paths inherit the model automatically. + +### Trust Boundaries + +Apache Superset's threat model assumes three trust boundaries. + +1. *The Admin role* is a fully trusted operational principal. Anything an Admin can do through the documented user interface, REST API, or configuration system is an intended capability, not a vulnerability, even if individually powerful or destructive. The Admin role is, by policy, equivalent to operating-system-level trust over the Apache Superset application. This is unavoidable rather than aspirational: an Admin can, for example, register new database connections of arbitrary type, execute arbitrary SQL through SQL Lab, render Jinja templates that resolve to SQL or rendered HTML, and override application configuration. Granting Admin is functionally equivalent to granting shell access on the host, which is the reasoning behind treating it as a trust boundary in the sense of MITRE CNA Operational Rules 4.1. + +2. *The operator* is whoever deploys, configures, and runs Apache Superset. Behaviors that depend on deployment-time decisions are the operator's responsibility, not Apache Superset's. This includes the values of secrets, the network reachability of the application and its data sources, the choice of database connectors and cache backends, the selection of feature flags, the destinations of notifications, and the trust placed in third-party plugins. Defaults that fail closed are the responsibility of the Apache Superset codebase. Defaults that fail open must be accompanied by a documented hardening requirement; applying that hardening is the operator's responsibility, while shipping an undocumented or unflagged fail-open default is a codebase issue. + +3. *The Apache Superset codebase* is responsible for enforcing the role and capability matrix below across its product surface. A failure to enforce, anywhere in that surface, is in scope. The codebase's commitments are limited to the role and capability matrix and to controls Apache Superset's own documentation (this file and the linked Security documentation) explicitly positions as security boundaries; configurable hardening that operators can layer on top is treated separately under *Vulnerability Scope* below. + +### Roles and Capabilities + +Apache Superset ships with the following first-class principals. Detailed permission definitions live in the [Security documentation](https://superset.apache.org/docs/security). + +| Principal | Read data | Write objects | Execute SQL | Manage databases | Manage users, roles, RLS | +|---|---|---|---|---|---| +| Public (anonymous) | none by default | no | no | no | no | +| Gamma | only granted datasets | own charts and dashboards on granted datasets | no by default (requires the `sql_lab` role) | no | no | +| Alpha | all data sources | own charts, dashboards, and datasets | no by default (requires the `sql_lab` role) | data upload to existing databases only | no | +| Admin | all | all | yes | yes | yes | +| Embedded guest token | data sources reachable through the embedded dashboards the token authorizes | no | no | no | no | + +The `sql_lab` role is *additive*: it grants the SQL Lab permission set on top of the base role above, and is the only path by which Gamma or Alpha gain SQL execution capability. Database access is still scoped per the base role's grants. Admin includes SQL Lab access by default. + +Deployments may grant or revoke individual view-menu permissions, which shifts the boundary for that deployment but does not redefine the model. Any custom role created by an operator inherits the same principle: its capabilities are whatever the operator has explicitly granted it. The Public principal follows the same rule: operators may grant the Public role read access to specific datasets or dashboards (typically for anonymous reporting use cases), which shifts the boundary for that deployment without redefining the model. + +### Vulnerability Scope + +The test for whether a finding is in scope is a single question: + +> *Does this finding let a principal perform an action the role and capability matrix above does not entitle them to?* + +If yes, it is in scope. If no, it is out of scope. The lists below apply that test to the classes Apache Superset most commonly receives reports about; they are illustrative, not exhaustive. + +*In Scope* + +- A user, embedded guest, or anonymous visitor reads, modifies, or deletes data outside their granted set. Includes object-level access bypass on charts, dashboards, datasets, saved queries, tags, annotations, and similar per-object endpoints, and row-level-security rule bypass. +- A user supplies input that the codebase should sanitize or parameterize but does not, causing arbitrary SQL, template code, or scripts to execute. Includes injection through Jinja templates, SQL-construction paths, and any field the codebase passes to a query engine or template engine. +- A user bypasses authentication, fixates or reuses another user's session, or reaches an authenticated endpoint without logging in. +- An embedded guest token authorizes actions outside the dashboard it was issued for, or can be forged, replayed, or escalated to a higher principal. +- Apache Superset, acting on behalf of an unprivileged user, fetches an outbound URL the user controls in a feature where Apache Superset itself, not the operator, controls the outbound destination set (server-side request forgery). +- An Apache Superset default fails open without an accompanying documented hardening requirement. The codebase is responsible for shipping fail-closed defaults or for documenting the hardening required when a default fails open; failures of that responsibility are in scope (see *Trust Boundaries*). +- A user bypasses a control Apache Superset documents specifically as a security boundary. This includes row-level security, the access checks tied to the role and capability matrix above, and any feature whose documentation positions it as security-relevant. The codebase commits to enforcing those controls; bypasses are in scope regardless of which principal triggers them. +- A user causes a script to execute in another user's browser through a field the codebase renders to that other user (cross-site scripting), or causes cross-origin leakage of authenticated session state or data. +- A user reaches a route, page, or API endpoint that requires a role they do not have. + +*Out of Scope* + +- Any action an Admin role can perform through documented configuration, API, or UI. The Admin role is a trusted operational principal by policy. Per MITRE CNA Operational Rules 4.1, a qualifying vulnerability must violate a security policy; behavior within a documented trust boundary does not. +- Deployment or operator decisions: the values of secrets and tokens, whether internal networks are reachable from the server, which database connectors or cache backends are enabled, which feature flags are set, where notifications are delivered, and which third-party plugins are loaded. +- Compromise, modification, or malicious control of trusted backend infrastructure. Apache Superset assumes the integrity of its metastore, cache backends (for example Redis or Memcached), message brokers, secret stores, and other operator-managed infrastructure. Findings that require an attacker to read from, write to, or otherwise tamper with these systems, including injecting malicious state, serialized objects, cache entries, task metadata, configuration, or database records, are post-compromise scenarios and do not constitute vulnerabilities in Apache Superset itself. A finding remains in scope only if an unprivileged user can cause such modification through a vulnerability in Apache Superset. +- Code paths whose intended purpose is example data, demos, fixtures, local development, or documentation, rather than the production runtime. +- How a downstream application (spreadsheet program, email client, browser handling user-downloaded files) interprets output Apache Superset produced for it. +- Findings without a reproducible proof of concept against a supported release. The burden of demonstrating exploitability rests with the reporter; findings closed for lack of a proof of concept may be refiled if one is later produced. +- Brute force, rate limiting, denial of service, or resource exhaustion that does not bypass a documented control. +- Missing security headers, banner or version disclosure, user or object enumeration through error messages or timing, and similar low-impact information disclosure that does not enable a further concrete exploit. +- Bypasses of configurable defense-in-depth hardening that Apache Superset does not document as a security boundary. Apache Superset is not a SQL or database firewall: operator-deployable filters such as SQL function or table denylists, URI restrictions on already-authorized database connectors, and similar belt-and-braces controls are provided to let operators layer hardening on top of the role and capability matrix, not as firewall-grade guarantees the codebase commits to. Findings against such hardening are improvements, not vulnerabilities, unless the documentation positions the specific control as security-relevant. +- Hardening suggestions that improve defense in depth but do not violate the security model. + +Findings in third-party dependencies fall into two cases. A finding in a transitive dependency, or in an operator-selected dependency that Apache Superset does not ship, is out of scope and should be reported to the dependency's maintainers. A finding caused by Apache Superset pinning a known-vulnerable version of a direct dependency it ships, or using a dependency in a way that creates a vulnerability the dependency itself does not have, remains in scope. Dependency findings in the official Apache Superset Docker image that fall into the first case can be remediated by extending the image at release time. + +When uncertain whether a finding falls in scope, please file it through the reporting process above. The triage team will classify it and explain the reasoning if it is closed as out of scope. + +**Outcome of Reports** + +Reports that are deemed out of scope for a CVE but represent valid security best practices or hardening opportunities are typically converted into public GitHub issues, where the community can contribute fixes alongside the maintainers. The triage decision and reasoning are communicated back to the reporter in either case. + +**Vulnerability Aggregation & CVE Attribution** + +In accordance with MITRE CNA Operational Rules (4.1.10, 4.1.11, and 4.2.13), Apache Superset issues CVEs based on the underlying architectural root cause rather than the number of affected endpoints or exploit payloads. +- Aggregation: If multiple exploit vectors stem from the same programmatic failure or shared vulnerable code, they must be aggregated into a single, comprehensive report. +- Independent Fixes: Separate CVEs will only be assigned if the vulnerabilities reside in decoupled architectural modules and can be fixed independently of one another. +Reports that fail to aggregate related findings will be merged during triage to ensure an accurate and defensible CVE record. + +**Your responsible disclosure and collaboration are invaluable.** + +## Extra Information + + - [Apache Superset documentation](https://superset.apache.org/docs/security) + - [Common Vulnerabilities and Exposures by release](https://superset.apache.org/docs/security/cves) + - [How Security Vulnerabilities are Reported & Handled in Apache Superset (Blog)](https://preset.io/blog/how-security-vulnerabilities-are-reported-and-handled-in-apache-superset/) + +**For LLM agents and automated scanners** + +This file is the canonical source of truth for what Apache Superset considers a security vulnerability. Automated tooling (LLM-based code scanners, static analyzers, dependency tools) should treat the Security Model section as authoritative when classifying findings. The repository's [AGENTS.md](AGENTS.md) file contains a short pointer to this document for agents that read AGENTS.md as their entry point. From c7bbfff47594a92c562d75ba1bab786e538ccba4 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Sat, 30 May 2026 20:39:38 -0700 Subject: [PATCH 07/10] fix(ci): gate welcome message on first-time contributor association (#40543) Co-authored-by: Claude Sonnet 4.6 --- .github/workflows/welcome-new-users.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/welcome-new-users.yml b/.github/workflows/welcome-new-users.yml index 090281153d37..d30215da3938 100644 --- a/.github/workflows/welcome-new-users.yml +++ b/.github/workflows/welcome-new-users.yml @@ -7,6 +7,7 @@ on: jobs: welcome: runs-on: ubuntu-24.04 + if: github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' permissions: pull-requests: write From 585745695c3228bd33a3910ecba9eaa43ab82364 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Sat, 30 May 2026 20:44:09 -0700 Subject: [PATCH 08/10] fix(chart): load viz_type from request params when creating chart via API (#40536) Co-authored-by: hdahme Co-authored-by: Claude Sonnet 4.6 --- superset/commands/chart/create.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/superset/commands/chart/create.py b/superset/commands/chart/create.py index 84b3aa29411e..e3d3ea93f330 100644 --- a/superset/commands/chart/create.py +++ b/superset/commands/chart/create.py @@ -34,6 +34,7 @@ from superset.commands.utils import get_datasource_by_id from superset.daos.chart import ChartDAO from superset.daos.dashboard import DashboardDAO +from superset.utils import json from superset.utils.decorators import on_error, transaction logger = logging.getLogger(__name__) @@ -43,6 +44,13 @@ class CreateChartCommand(CreateMixin, BaseCommand): def __init__(self, data: dict[str, Any]): self._properties = data.copy() + if params_str := self._properties.get("params"): + params = json.loads(params_str) + if isinstance(params, dict) and "viz_type" in params: + # Only fall back to params when no top-level viz_type was supplied; + # an explicit top-level field takes precedence. + self._properties.setdefault("viz_type", params["viz_type"]) + @transaction(on_error=partial(on_error, reraise=ChartCreateFailedError)) def run(self) -> Model: self.validate() From 469979714f33f66649593b4f194023c7cee65704 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Sat, 30 May 2026 20:54:45 -0700 Subject: [PATCH 09/10] chore(deps): force serialize-javascript 7.0.5 in docs (#40540) Co-authored-by: Claude Code --- docs/package.json | 3 ++- docs/yarn.lock | 10 ++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/package.json b/docs/package.json index 7757dc4dc9b0..8497d523e883 100644 --- a/docs/package.json +++ b/docs/package.json @@ -132,7 +132,8 @@ "lodash": "4.18.1", "lodash-es": "4.18.1", "yaml": "1.10.3", - "uuid": "11.1.1" + "uuid": "11.1.1", + "serialize-javascript": "7.0.5" }, "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610" } diff --git a/docs/yarn.lock b/docs/yarn.lock index 64bf2e9e4773..7362d428247f 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -13362,12 +13362,10 @@ serialize-error@^8.1.0: dependencies: type-fest "^0.20.2" -serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" - integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== - dependencies: - randombytes "^2.1.0" +serialize-javascript@7.0.5, serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "7.0.5" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-7.0.5.tgz#c798cc0552ffbb08981914a42a8756e339d0d5b1" + integrity sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw== serve-handler@^6.1.7: version "6.1.7" From a340293fefe61114b128bb70e6c703fcdd1885fd Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Sat, 30 May 2026 21:08:27 -0700 Subject: [PATCH 10/10] chore(deps): bump idna, Authlib, fontTools, python-ldap, virtualenv (#40560) Co-authored-by: Claude Code --- requirements/base.txt | 2 +- requirements/development.txt | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 68dddfa79d97..d62bf8c8059d 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -176,7 +176,7 @@ holidays==0.82 # via apache-superset (pyproject.toml) humanize==4.12.3 # via apache-superset (pyproject.toml) -idna==3.10 +idna==3.15 # via # email-validator # requests diff --git a/requirements/development.txt b/requirements/development.txt index 99d0839267ec..edac723c51c7 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -52,7 +52,7 @@ attrs==25.3.0 # referencing # requests-cache # trio -authlib==1.6.9 +authlib==1.6.12 # via fastmcp babel==2.17.0 # via @@ -317,7 +317,7 @@ flask-wtf==1.2.2 # -c requirements/base-constraint.txt # apache-superset # flask-appbuilder -fonttools==4.55.0 +fonttools==4.60.2 # via matplotlib freezegun==1.5.1 # via apache-superset @@ -422,7 +422,7 @@ humanize==4.12.3 # apache-superset identify==2.5.36 # via pre-commit -idna==3.10 +idna==3.15 # via # -c requirements/base-constraint.txt # anyio @@ -838,7 +838,7 @@ python-dotenv==1.2.2 # apache-superset # fastmcp # pydantic-settings -python-ldap==3.4.4 +python-ldap==3.4.5 # via apache-superset python-multipart==0.0.29 # via mcp @@ -1090,7 +1090,7 @@ vine==5.1.0 # amqp # celery # kombu -virtualenv==20.29.2 +virtualenv==20.36.1 # via pre-commit watchdog==6.0.0 # via