docs: bifurcate documentation into user and admin sections (#38196)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Evan Rusackas
2026-02-26 16:29:08 -05:00
committed by GitHub
parent 8a053bbe07
commit 6589ee48f9
171 changed files with 10899 additions and 2866 deletions

View File

@@ -0,0 +1,130 @@
---
title: CVEs fixed by release
sidebar_position: 2
---
#### Version 5.0.0
| CVE | Title | Affected |
|:---------------|:-----------------------------------------------------------------------------------|---------:|
| CVE-2025-55673 | Exposure of Sensitive Information to an Unauthorized Actor | < 5.0.0 |
| CVE-2025-55674 | Improper Neutralization of Special Elements used in an SQL Command | < 5.0.0 |
| CVE-2025-55675 | Improper Access Control leading to Information Disclosure | < 5.0.0 |
#### Version 4.1.3
| CVE | Title | Affected |
|:---------------|:-----------------------------------------------------------------------------------|---------:|
| CVE-2025-55672 | Improper Neutralization of Input During Web Page Generation | < 4.1.3 |
#### Version 4.1.2
| CVE | Title | Affected |
|:---------------|:-----------------------------------------------------------------------------------|---------:|
| CVE-2025-27696 | Improper authorization leading to resource ownership takeover | < 4.1.2 |
| CVE-2025-48912 | Improper authorization bypass on row level security via SQL Injection | < 4.1.2 |
#### Version 4.1.0
| CVE | Title | Affected |
|:---------------|:-----------------------------------------------------------------------------------|---------:|
| CVE-2024-53947 | Improper SQL authorisation, parse for specific postgres functions | < 4.1.0 |
| CVE-2024-53948 | Error verbosity exposes metadata in analytics databases | < 4.1.0 |
| CVE-2024-53949 | Lower privilege users are able to create Role when FAB_ADD_SECURITY_API is enabled | < 4.1.0 |
| CVE-2024-55633 | SQLLab Improper readonly query validation allows unauthorized write access | < 4.1.0 |
#### Version 4.0.2
| CVE | Title | Affected |
|:---------------|:----------------------------|---------:|
| CVE-2024-39887 | Improper SQL authorization | < 4.0.1 |
#### Version 3.1.3, 4.0.1
| CVE | Title | Affected |
|:---------------|:----------------------------|----------------------------:|
| CVE-2024-34693 | Server arbitrary file read | < 3.1.3, >= 4.0.0, < 4.0.1 |
#### Version 3.1.2
| CVE | Title | Affected |
|:---------------|:--------------------------------------------------------|---------:|
| CVE-2024-28148 | Incorrect datasource authorization on explore REST API | < 3.1.2 |
#### Version 3.0.4, 3.1.1
| CVE | Title | Affected |
|:---------------|:-----------------------------------------------------------------------------|----------------------------:|
| CVE-2024-27315 | Improper error handling on alerts | < 3.0.4, >= 3.1.0, < 3.1.1 |
| CVE-2024-24773 | Improper validation of SQL statements allows for unauthorized access to data | < 3.0.4, >= 3.1.0, < 3.1.1 |
| CVE-2024-24772 | Improper Neutralisation of custom SQL on embedded context | < 3.0.4, >= 3.1.0, < 3.1.1 |
| CVE-2024-24779 | Improper data authorization when creating a new dataset | < 3.0.4, >= 3.1.0, < 3.1.1 |
| CVE-2024-26016 | Improper authorization validation on dashboards and charts import | < 3.0.4, >= 3.1.0, < 3.1.1 |
#### Version 3.0.3
| CVE | Title | Affected |
|:---------------|:----------------------------------------------|---------:|
| CVE-2023-49657 | Stored XSS in Dashboard Title and Chart Title | < 3.0.3 |
#### Version 3.0.2, 2.1.3
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------|---------------------------:|
| CVE-2023-46104 | Allows for uncontrolled resource consumption via a ZIP bomb | < 2.1.3, >= 3.0.0, < 3.0.2 |
| CVE-2023-49736 | SQL Injection on where_in JINJA macro | < 2.1.3, >= 3.0.0, < 3.0.2 |
| CVE-2023-49734 | Privilege Escalation Vulnerability | < 2.1.3, >= 3.0.0, < 3.0.2 |
#### Version 3.0.0
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------------------|---------:|
| CVE-2023-42502 | Open Redirect Vulnerability | < 3.0.0 |
| CVE-2023-42505 | Sensitive information disclosure on db connection details | < 3.0.0 |
#### Version 2.1.3
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------------------|---------:|
| CVE-2023-42504 | Lack of rate limiting allows for possible denial of service | < 2.1.3 |
#### Version 2.1.2
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------------------|---------:|
| CVE-2023-40610 | Privilege escalation with default examples database | < 2.1.2 |
| CVE-2023-42501 | Unnecessary read permissions within the Gamma role | < 2.1.2 |
| CVE-2023-43701 | Stored XSS on API endpoint | < 2.1.2 |
#### Version 2.1.1
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------------------|---------:|
| CVE-2023-36387 | Improper API permission for low privilege users | < 2.1.1 |
| CVE-2023-36388 | Improper API permission for low privilege users allows for SSRF | < 2.1.1 |
| CVE-2023-27523 | Improper data permission validation on Jinja templated queries | < 2.1.1 |
| CVE-2023-27526 | Improper Authorization check on import charts | < 2.1.1 |
| CVE-2023-39264 | Stack traces enabled by default | < 2.1.1 |
| CVE-2023-39265 | Possible Unauthorized Registration of SQLite Database Connections | < 2.1.1 |
| CVE-2023-37941 | Metadata db write access can lead to remote code execution | < 2.1.1 |
| CVE-2023-32672 | SQL parser edge case bypasses data access authorization | < 2.1.1 |
#### Version 2.1.0
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------------------|---------:|
| CVE-2023-25504 | Possible SSRF on import datasets | < 2.1.0 |
| CVE-2023-27524 | Session validation vulnerability when using provided default SECRET_KEY | < 2.1.0 |
| CVE-2023-27525 | Incorrect default permissions for Gamma role | < 2.1.0 |
| CVE-2023-30776 | Database connection password leak | < 2.1.0 |
#### Version 2.0.1
| CVE | Title | Affected |
|:---------------|:------------------------------------------------------------|------------------: |
| CVE-2022-41703 | SQL injection vulnerability in adhoc clauses | < 2.0.1 or < 1.5.2 |
| CVE-2022-43717 | Cross-Site Scripting on dashboards | < 2.0.1 or < 1.5.2 |
| CVE-2022-43718 | Cross-Site Scripting vulnerability on upload forms | < 2.0.1 or < 1.5.2 |
| CVE-2022-43719 | Cross Site Request Forgery (CSRF) on accept, request access | < 2.0.1 or < 1.5.2 |
| CVE-2022-43720 | Improper rendering of user input | < 2.0.1 or < 1.5.2 |
| CVE-2022-43721 | Open Redirect Vulnerability | < 2.0.1 or < 1.5.2 |
| CVE-2022-45438 | Dashboard metadata information leak | < 2.0.1 or < 1.5.2 |

View File

@@ -0,0 +1,179 @@
---
title: Securing Your Superset Installation for Production
sidebar_position: 3
---
> *This guide applies to Apache Superset version 4.0 and later and is an evolving set of best practices that administrators should adapt to their specific deployment architecture.*
The default Apache Superset configuration is optimized for ease of use and development, not for security. For any production deployment, it is **critical** that you review and apply the following security configurations to harden your instance, protect user data, and prevent unauthorized access.
This guide provides a comprehensive checklist of essential security configurations and best practices.
### **Critical Prerequisites: HTTPS/TLS Configuration**
Running Superset without HTTPS (TLS) is not secure. Without it, all network traffic—including user credentials, session tokens, and sensitive data—is sent in cleartext and can be easily intercepted.
* **Use a Reverse Proxy:** Your Superset instance should always be deployed behind a reverse proxy (e.g., Nginx, Traefik) or a load balancer (e.g., AWS ALB, Google Cloud Load Balancer) that is configured to handle HTTPS termination.
* **Enforce Modern TLS:** Configure your proxy to enforce TLS 1.2 or higher with strong, industry-standard cipher suites.
* **Implement HSTS:** Use the HTTP Strict Transport Security (HSTS) header to ensure browsers only connect to your Superset instance over HTTPS. This can be configured in your reverse proxy or within Superset's Talisman settings.
### **`SUPERSET_SECRET_KEY` Management (CRITICAL)**
This is the most critical security setting for your Superset instance. It is used to sign all session cookies and encrypt sensitive information in the metadata database, such as database connection credentials.
* **Generate a Unique, Strong Key:** A unique key must be generated for every Superset instance. Use a cryptographically secure method to create it.
```bash
# Example using openssl to generate a strong key
openssl rand -base64 42
```
* **Store the Key Securely:** The key must be kept confidential. The recommended approach is to store it as an environment variable or in a secrets management system (e.g., AWS Secrets Manager, HashiCorp Vault). **Do not hardcode the key in `superset_config.py` or commit it to version control.**
```python
# In superset_config.py
import os
SECRET_KEY = os.environ.get('SUPERSET_SECRET_KEY')
```
> #### ⚠️ Warning: Your `SUPERSET_SECRET_KEY` Must Be Unique
>
> **NEVER** reuse the same `SUPERSET_SECRET_KEY` across different environments (e.g., development, staging, production) or different Superset instances. Reusing a key allows cryptographically signed session cookies to be used across those instances, which can lead to a full authentication bypass if a cookie is compromised. Treat this key like a master password.
### **Session Management Security (CRITICAL)**
Properly configuring user sessions is essential to prevent session hijacking and ensure that sessions are terminated correctly.
#### **Use a Server-Side Session Backend (Strongly Recommended for Production)**
The default stateless cookie-based session handling presents challenges for immediate session invalidation upon logout. For all production deployments, we strongly recommend configuring an optional server-side session backend like Redis, Memcached, or a database. This ensures that session data is stored securely on the server and can be instantly destroyed upon logout, rendering any copied session cookies immediately useless.
**Example `superset_config.py` for Redis:**
```python
# superset_config.py
from redis import Redis
import os
# 1. Enable server-side sessions
SESSION_SERVER_SIDE = True
# 2. Choose your backend (e.g., 'redis', 'memcached', 'filesystem', 'sqlalchemy')
SESSION_TYPE = 'redis'
# 3. Configure your Redis connection
# Use environment variables for sensitive details
SESSION_REDIS = Redis(
host=os.environ.get('REDIS_HOST', 'localhost'),
port=int(os.environ.get('REDIS_PORT', 6379)),
password=os.environ.get('REDIS_PASSWORD'),
db=int(os.environ.get('REDIS_DB', 0)),
ssl=os.environ.get('REDIS_SSL_ENABLED', 'True').lower() == 'true',
ssl_cert_reqs='required' # Or another appropriate SSL setting
)
# 4. Ensure the session cookie is signed for integrity
SESSION_USE_SIGNER = True
```
#### **Configure Session Lifetime and Cookie Security Flags**
This is mandatory for *all* deployments, whether stateless or server-side.
```python
# superset_config.py
from datetime import timedelta
# Set a short absolute session timeout
# The default is 31 days, which is NOT recommended for production.
PERMANENT_SESSION_LIFETIME = timedelta(hours=8)
# Enforce secure cookie flags to prevent browser-based attacks
SESSION_COOKIE_SECURE = True # Transmit cookie only over HTTPS
SESSION_COOKIE_HTTPONLY = True # Prevent client-side JS from accessing the cookie
SESSION_COOKIE_SAMESITE = 'Lax' # Provide protection against CSRF attacks
```
> ##### Note on iFrame Embedding and `SESSION_COOKIE_SAMESITE`
>The recommended default setting `'Lax'` provides good CSRF protection for most use cases. However, if you need to embed Superset dashboards into other applications using an iFrame, you will need to change this setting to `'None'`.
SESSION_COOKIE_SAMESITE = 'None'
Setting SameSite to 'None' requires that SESSION_COOKIE_SECURE is also set to True. Be aware that this configuration disables some of the browser's built-in CSRF protections to allow for cross-domain functionality, so it should only be used when iFrame embedding is necessary.
### **Authentication and Authorization**
While Superset's built-in database authentication is convenient, for production it's highly recommended to integrate with an enterprise-grade identity provider (IdP).
* **Use an Enterprise IdP:** Configure authentication via OAuth or LDAP to leverage your organization's existing identity management system. This provides benefits like Single Sign-On (SSO), Multi-Factor Authentication (MFA), and centralized user provisioning/deprovisioning.
* **Principle of Least Privilege:** Assign users to the most restrictive roles necessary for their jobs. Avoid over-provisioning users with Admin or Alpha roles, and ensure row-level security is applied where appropriate.
* **Admin Accounts:** Delete or disable the default admin user after a new administrative account has been configured.
### **Content Security Policy (CSP) and Other Headers**
Superset can use Flask-Talisman to set security headers. However, it must be explicitly enabled.
> #### ⚠️ Important: Talisman is Disabled by Default
>
> In Superset 4.0 and later, Talisman is disabled by default (`TALISMAN_ENABLED = False`). You **must** explicitly enable it in your `superset_config.py` for the security headers defined in `TALISMAN_CONFIG` to take effect.
Here's the documentation section how how to set up Talisman: https://superset.apache.org/admin-docs/security/#content-security-policy-csp
### **Database Security**
> #### ❗ Superset is Not a Database Firewall
>
> It is essential to understand that **Apache Superset is a data visualization and exploration platform, not a database firewall or a comprehensive security solution for your data warehouse.** While Superset provides features to help manage data access, the ultimate responsibility for securing your underlying databases lies with your database administrators (DBAs) and security teams. This includes managing network access, user privileges, and fine-grained permissions directly within the database. The configurations below are an important secondary layer of security but should not be your only line of defense.
* **Use a Dedicated Database User:** The database connection configured in Superset should use a dedicated, limited-privilege database user. This user should only have the minimum required permissions (e.g., `SELECT` on specific schemas) for the data sources it needs to query. It should **not** have `INSERT`, `UPDATE`, `DELETE`, or administrative privileges.
* **Restrict Dangerous SQL Functions:** To mitigate potential SQL injection risks, configure the `DISALLOWED_SQL_FUNCTIONS` list in your `superset_config.py`. Be aware that this is a defense-in-depth measure, not a substitute for proper database permissions.
### **Additional Security Layers**
* **Web Application Firewall (WAF):** Deploying Superset behind a WAF (e.g., Cloudflare, AWS WAF) is strongly recommended. A WAF with a standard ruleset (like the OWASP Core Rule Set) provides a critical layer of defense against common attacks like SQL Injection, XSS, and remote code execution.
### **Monitoring and Logging**
* **Configure Structured Logging:** Set up a robust logging configuration to capture important security events.
* **Centralize Logs:** Ship logs from all Superset components (frontend, worker, etc.) to a centralized SIEM (Security Information and Event Management) system for analysis and alerting.
* **Monitor Key Events:** Create alerts for suspicious activities, including:
* Multiple failed login attempts for a single user or from a single IP address.
* Changes to user roles or permissions.
* Creation or deletion of high-privilege users.
* Attempts to use disallowed SQL functions.
-----
### **Appendix A: Production Deployment Checklist**
#### **Initial Setup:**
- [ ] HTTPS/TLS is configured and enforced via a reverse proxy.
- [ ] A unique, strong `SUPERSET_SECRET_KEY` is generated and secured in an environment variable or secrets vault.
- [ ] Server-side session management is configured (e.g., Redis).
- [ ] `PERMANENT_SESSION_LIFETIME` is set to a short duration (e.g., 8 hours).
- [ ] All session cookie security flags (`Secure`, `HttpOnly`, `SameSite`) are enabled.
- [ ] `DEBUG` mode is set to `False`.
- [ ] Talisman is explicitly enabled and configured with a strict Content Security Policy.
- [ ] Database connections use dedicated, limited-privilege accounts.
- [ ] Authentication is integrated with an enterprise identity provider (OAuth/LDAP).
- [ ] A Web Application Firewall (WAF) is deployed in front of Superset.
- [ ] Logging is configured and logs are shipped to a central monitoring system.
#### **Ongoing Maintenance:**
- [ ] Regularly update to the latest major or minor versions of Superset. Those versions receive up-to-date security patches.
- [ ] Rotate the `SUPERSET_SECRET_KEY` periodically (e.g., quarterly) and after any potential security incident.
- [ ] Conduct quarterly access reviews for all users.
- [ ] Assuming logging and monitoring is in place, review security monitoring alerts weekly.
### **Appendix B: `SECRET_KEY` Rotation and Compromise Response**
**Why and When to Rotate the `SECRET_KEY`**
Rotating the `SUPERSET_SECRET_KEY` is a critical security procedure. It is mandatory after a known or suspected compromise and is a best practice when an employee with access to the key departs. While periodic rotation can limit the window of exposure for an unknown leak, it is a high-impact operation that will invalidate all user sessions and requires careful execution to avoid breaking your instance. The principles behind managing this key align with general best practices for cryptographic storage, which are further detailed in the OWASP Cryptographic Storage Cheat Sheet here: https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html
**Procedure for Rotating the Key**
The procedure for safely rotating the SECRET_KEY must be followed precisely to avoid locking yourself out of your instance. The official Apache Superset documentation maintains the correct, up-to-date procedure. Please follow the official guide here:
https://superset.apache.org/admin-docs/configuration/configuring-superset/#rotating-to-a-newer-secret_key
:::resources
- [Blog: Running Apache Superset on the Open Internet](https://preset.io/blog/running-apache-superset-on-the-open-internet-a-report-from-the-fireline/)
- [Blog: How Security Vulnerabilities are Reported & Handled in Apache Superset](https://preset.io/blog/how-security-vulnerabilities-are-reported-and-handled-in-apache-superset/)
:::

View File

@@ -0,0 +1,452 @@
---
title: Security Configurations
sidebar_position: 1
---
Authentication and authorization in Superset is handled by Flask AppBuilder (FAB), an application development framework
built on top of Flask. FAB provides authentication, user management, permissions and roles.
Please read its [Security documentation](https://flask-appbuilder.readthedocs.io/en/latest/security.html).
### Provided Roles
Superset ships with a set of roles that are handled by Superset itself. You can assume
that these roles will stay up-to-date as Superset evolves (and as you update Superset versions).
Even though **Admin** users have the ability, we don't recommend altering the
permissions associated with each role (e.g. by removing or adding permissions to them). The permissions
associated with each role will be re-synchronized to their original values when you run
the **superset init** command (often done between Superset versions).
A table with the permissions for these roles can be found at [/RESOURCES/STANDARD_ROLES.md](https://github.com/apache/superset/blob/master/RESOURCES/STANDARD_ROLES.md).
### Admin
Admins have all possible rights, including granting or revoking rights from other
users and altering other peoples slices and dashboards.
### Alpha
Alpha users have access to all data sources, but they cannot grant or revoke access
from other users. They are also limited to altering the objects that they own. Alpha users can add and alter data sources.
### Gamma
Gamma users have limited access. They can only consume data coming from data sources
they have been given access to through another complementary role. They only have access to
view the slices and dashboards made from data sources that they have access to. Currently Gamma
users are not able to alter or add data sources. We assume that they are mostly content consumers, though they can create slices and dashboards.
Also note that when Gamma users look at the dashboards and slices list view, they will
only see the objects that they have access to.
### sql_lab
The **sql_lab** role grants access to SQL Lab. Note that while **Admin** users have access
to all databases by default, both **Alpha** and **Gamma** users need to be given access on a per database basis.
### Public
The **Public** role is the most restrictive built-in role, designed specifically for anonymous/unauthenticated
users who need to view dashboards. It provides minimal read-only access for:
- Viewing dashboards and charts
- Using interactive dashboard filters
- Accessing dashboard and chart permalinks
- Reading embedded dashboards
- Viewing annotations on charts
The Public role explicitly excludes:
- Any write permissions on dashboards, charts, or datasets
- SQL Lab access
- Share functionality
- User profile or admin features
- Menu access to most Superset features
Anonymous users are automatically assigned the Public role when `AUTH_ROLE_PUBLIC` is configured
(a Flask-AppBuilder setting). The `PUBLIC_ROLE_LIKE` setting is **optional** and controls what
permissions are synced to the Public role when you run `superset init`:
```python
# Optional: Sync sensible default permissions to the Public role
PUBLIC_ROLE_LIKE = "Public"
# Alternative: Copy permissions from Gamma for broader access
# PUBLIC_ROLE_LIKE = "Gamma"
```
If you prefer to manually configure the Public role's permissions (or use `DASHBOARD_RBAC` to
grant access at the dashboard level), you do not need to set `PUBLIC_ROLE_LIKE`.
**Important notes:**
- **Data access is still required:** The Public role only grants UI/API permissions. You must
also grant access to specific datasets necessary to view a dashboard. As with other roles,
this can be done in two ways:
- **Without `DASHBOARD_RBAC`:** Dashboards only appear in the list and are accessible if
the user has permission to at least one of their datasets. Grant dataset access by editing
the Public role in the Superset UI (Menu → Security → List Roles → Public) and adding the
relevant data sources. All published dashboards using those datasets become visible.
- **With `DASHBOARD_RBAC` enabled:** Anonymous users will only see dashboards where the
"Public" role has been explicitly added in the dashboard's properties. Dataset permissions
are not required—DASHBOARD_RBAC handles the cascading permissions check. This provides
fine-grained control over which dashboards are publicly visible.
- **Role synchronization:** Built-in role permissions (Admin, Alpha, Gamma, sql_lab, and Public
when `PUBLIC_ROLE_LIKE = "Public"`) are synchronized when you run `superset init`. Any manual
permission edits to these roles may be overwritten during upgrades. To customize the Public
role permissions, you can either:
- Edit the Public role directly and avoid setting `PUBLIC_ROLE_LIKE` (permissions won't be
overwritten by `superset init`)
- Copy the Public role via "Copy Role" in the Superset web UI, save it under a different name
(e.g., "Public_Custom"), customize the permissions, then update **both** configs:
`PUBLIC_ROLE_LIKE = "Public_Custom"` and `AUTH_ROLE_PUBLIC = "Public_Custom"`
### Managing Data Source Access for Gamma Roles
Heres how to provide users access to only specific datasets. First make sure the users with
limited access have [only] the Gamma role assigned to them. Second, create a new role (Menu -> Security -> List Roles) and click the + sign.
This new window allows you to give this new role a name, attribute it to users and select the
tables in the **Permissions** dropdown. To select the data sources you want to associate with this role, simply click on the dropdown and use the typeahead to search for your table names.
You can then confirm with users assigned to the **Gamma** role that they see the
objects (dashboards and slices) associated with the tables you just extended them.
### Dashboard Access Control
Access to dashboards is managed via owners (users that have edit permissions to the dashboard).
Non-owner user access can be managed in two ways. Note that dashboards must be published to be
visible to other users.
#### Dataset-Based Access (Default)
By default, users can view published dashboards if they have access to at least one dataset
used in that dashboard. Grant dataset access by adding the relevant data source permissions
to a role (Menu → Security → List Roles).
This is the simplest approach but provides all-or-nothing access based on dataset permissions—
if a user has access to a dataset, they can see all published dashboards using that dataset.
#### Dashboard-Level Access (DASHBOARD_RBAC)
For fine-grained control over which dashboards specific roles can access, enable the
`DASHBOARD_RBAC` feature flag:
```python
FEATURE_FLAGS = {
"DASHBOARD_RBAC": True,
}
```
With this enabled, you can assign specific roles to each dashboard in its properties. Users
will only see dashboards where their role is explicitly added.
**Important considerations:**
- Dashboard access **bypasses** dataset-level checks—granting a role access to a dashboard
implicitly grants read access to all charts and datasets in that dashboard
- Dashboards without any assigned roles fall back to dataset-based access
- The dashboard must still be published to be visible
This feature is particularly useful for:
- Making specific dashboards public while keeping others private
- Granting access to dashboards without exposing the underlying datasets for other uses
- Creating dashboard-specific access patterns that don't align with dataset ownership
### SQL Execution Security Considerations
Apache Superset includes features designed to provide safeguards when interacting with connected databases, such as the `DISALLOWED_SQL_FUNCTIONS` configuration setting. This aims to prevent the execution of potentially harmful database functions or system variables directly from Superset interfaces like SQL Lab.
However, it is crucial to understand the following:
**Superset is Not a Database Firewall**: Superset's built-in checks, like `DISALLOWED_SQL_FUNCTIONS`, provide a layer of protection but cannot guarantee complete security against all database-level threats or advanced bypass techniques (like specific comment injection methods). They should be viewed as a supplement to, not a replacement for, robust database security.
**Configuration is Key**: The effectiveness of Superset's safeguards heavily depends on proper configuration by the Superset administrator. This includes maintaining the `DISALLOWED_SQL_FUNCTIONS` list, carefully managing feature flags (like `ENABLE_TEMPLATE_PROCESSING`), and configuring other security settings appropriately.
**Database Security is Paramount**: The ultimate responsibility for securing database access, controlling permissions, and preventing unauthorized function execution lies with the database administrators (DBAs) and security teams managing the underlying database instance.
**Recommended Database Practices**: We strongly recommend implementing security best practices at the database level, including:
* **Least Privilege**: Connecting Superset using dedicated database user accounts with the minimum permissions required for Superset's operation (typically read-only access to necessary schemas/tables).
* **Database Roles & Permissions**: Utilizing database-native roles and permissions to restrict access to sensitive functions, system variables (like `@@hostname`), schemas, or tables.
* **Network Security**: Employing network-level controls like database firewalls or proxies to restrict connections.
* **Auditing**: Enabling database-level auditing to monitor executed queries and access patterns.
By combining Superset's configurable safeguards with strong database-level security practices, you can achieve a more robust and layered security posture.
### REST API for user & role management
Flask-AppBuilder supports a REST API for user CRUD,
but this feature is in beta and is not enabled by default in Superset.
To enable this feature, set the following in your Superset configuration:
```python
FAB_ADD_SECURITY_API = True
```
Once configured, the documentation for additional "Security" endpoints will be visible in Swagger for you to explore.
### Customizing Permissions
The permissions exposed by FAB are very granular and allow for a great level of
customization. FAB creates many permissions automatically for each model that is
created (can_add, can_delete, can_show, can_edit, …) as well as for each view.
On top of that, Superset can expose more granular permissions like **all_datasource_access**.
**We do not recommend altering the 3 base roles as there are a set of assumptions that
Superset is built upon**. It is possible though for you to create your own roles, and union them to existing ones.
### Permissions
Roles are composed of a set of permissions, and Superset has many categories of
permissions. Here are the different categories of permissions:
- Model & Action: models are entities like Dashboard, Slice, or User. Each model has
a fixed set of permissions, like **can_edit**, **can_show**, **can_delete**, **can_list**, **can_add**,
and so on. For example, you can allow a user to delete dashboards by adding **can_delete** on
Dashboard entity to a role and granting this user that role.
- Views: views are individual web pages, like the Explore view or the SQL Lab view.
When granted to a user, they will see that view in its menu items, and be able to load that page.
- Data source: For each data source, a permission is created. If the user does not have the
`all_datasource_access permission` granted, the user will only be able to see Slices or explore the data sources that are granted to them
- Database: Granting access to a database allows for the user to access all
data sources within that database, and will enable the user to query that
database in SQL Lab, provided that the SQL Lab specific permission have been granted to the user
### Restricting Access to a Subset of Data Sources
We recommend giving a user the **Gamma** role plus any other roles that would add
access to specific data sources. We recommend that you create individual roles for
each access profile. For example, the users on the Finance team might have access to a set of
databases and data sources; these permissions can be consolidated in a single role.
Users with this profile then need to be assigned the **Gamma** role as a foundation to
the models and views they can access, and that Finance role that is a collection of permissions to data objects.
A user can have multiple roles associated with them. For example, an executive on the Finance
team could be granted **Gamma**, **Finance**, and the **Executive** roles. The **Executive**
role could provide access to a set of data sources and dashboards made available only to executives.
In the **Dashboards** view, a user can only see the ones they have access to
based on the roles and permissions that were attributed.
### Row Level Security
Using Row Level Security filters (under the **Security** menu) you can create filters
that are assigned to a particular table, as well as a set of roles.
If you want members of the Finance team to only have access to
rows where `department = "finance"`, you could:
- Create a Row Level Security filter with that clause (`department = "finance"`)
- Then assign the clause to the **Finance** role and the table it applies to
The **clause** field, which can contain arbitrary text, is then added to the generated
SQL statements WHERE clause. So you could even do something like create a filter
for the last 30 days and apply it to a specific role, with a clause
like `date_field > DATE_SUB(NOW(), INTERVAL 30 DAY)`. It can also support
multiple conditions: `client_id = 6` AND `advertiser="foo"`, etc.
All relevant Row level security filters will be combined together (under the hood,
the different SQL clauses are combined using AND statements). This means it's
possible to create a situation where two roles conflict in such a way as to limit a table subset to empty.
For example, the filters `client_id=4` and `client_id=5`, applied to a role,
will result in users of that role having `client_id=4` AND `client_id=5`
added to their query, which can never be true.
### User Sessions
Superset uses [Flask](https://pypi.org/project/Flask/)
and [Flask-Login](https://pypi.org/project/Flask-Login/) for user session management.
Session cookies are used to maintain session info and user state between requests,
although they do not contain personal user information they serve the purpose of identifying
a user session on the server side.
The session cookie is encrypted with the application `SECRET_KEY` and cannot be read by the client.
So it's very important to keep the `SECRET_KEY` secret and set to a secure unique complex random value.
Flask and Flask-Login offer a number of configuration options to control session behavior.
- Relevant Flask settings:
`SESSION_COOKIE_HTTPONLY`: (default: `False`): Controls if cookies should be set with the `HttpOnly` flag.
`SESSION_COOKIE_SECURE`: (default: `False`) Browsers will only send cookies with requests over
HTTPS if the cookie is marked “secure”. The application must be served over HTTPS for this to make sense.
`SESSION_COOKIE_SAMESITE`: (default: "Lax") Prevents the browser from sending this cookie along with cross-site requests.
`PERMANENT_SESSION_LIFETIME`: (default: "31 days") The lifetime of a permanent session as a `datetime.timedelta` object.
#### Switching to server side sessions
Server side sessions offer benefits over client side sessions on security and performance.
By enabling server side sessions, the session data is stored server side and only a session ID
is sent to the client. When a user logs in, a session is created server side and the session ID
is sent to the client in a cookie. The client will send the session ID with each request and the
server will use it to retrieve the session data.
On logout, the session is destroyed server side and the session cookie is deleted on the client side.
This reduces the risk for replay attacks and session hijacking.
Superset uses [Flask-Session](https://flask-session.readthedocs.io/en/latest/) to manage server side sessions.
To enable this extension you have to set:
``` python
SESSION_SERVER_SIDE = True
```
Flask-Session offers multiple backend session interfaces for Flask, here's an example for Redis:
``` python
from redis import Redis
SESSION_TYPE = "redis"
SESSION_REDIS = Redis(host="redis", port=6379, db=0)
# sign the session cookie sid
SESSION_USE_SIGNER = True
```
### Content Security Policy (CSP)
Superset uses the [Talisman](https://pypi.org/project/flask-talisman/) extension to enable implementation of a
[Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), an added
layer of security that helps to detect and mitigate certain types of attacks, including
Cross-Site Scripting (XSS) and data injection attacks.
A CSP makes it possible for server administrators to reduce or eliminate the vectors by which XSS can
occur by specifying the domains that the browser should consider to be valid sources of executable scripts.
A CSP-compatible browser will then only execute scripts loaded in source files received from those allowed domains,
ignoring all other scripts (including inline scripts and event-handling HTML attributes).
A policy is described using a series of policy directives, each of which describes the policy for
a certain resource type or policy area. You can check possible directives
[here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy).
It's extremely important to correctly configure a Content Security Policy when deploying Superset to
prevent many types of attacks. Superset provides two variables in `config.py` for deploying a CSP:
- `TALISMAN_ENABLED` defaults to `True`; set this to `False` in order to disable CSP
- `TALISMAN_CONFIG` holds the actual the policy definition (*see example below*) as well as any
other arguments to be passed to Talisman.
When running in production mode, Superset will check at startup for the presence
of a CSP. If one is not found, it will issue a warning with the security risks. For environments
where CSP policies are defined outside of Superset using other software, administrators can disable
this warning using the `CONTENT_SECURITY_POLICY_WARNING` key in `config.py`.
#### CSP Requirements
- Superset needs the `style-src unsafe-inline` CSP directive in order to operate.
```
style-src 'self' 'unsafe-inline'
```
- Only scripts marked with a [nonce](https://content-security-policy.com/nonce/) can be loaded and executed.
Nonce is a random string automatically generated by Talisman on each page load.
You can get current nonce value by calling jinja macro `csp_nonce()`.
```html
<script nonce="{{ csp_nonce() }}">
/* my script */
</script>
```
- Some dashboards load images using data URIs and require `data:` in their `img-src`
```
img-src 'self' data:
```
- MapBox charts use workers and need to connect to MapBox servers in addition to the Superset origin
```
worker-src 'self' blob:
connect-src 'self' https://api.mapbox.com https://events.mapbox.com
```
- Cartodiagram charts request map data (image and json) from external resources that can be edited by users,
and therefore either require a list of allowed domains to request from or a wildcard (`'*'`) for `img-src` and `connect-src`.
- Other CSP directives default to `'self'` to limit content to the same origin as the Superset server.
In order to adjust provided CSP configuration to your needs, follow the instructions and examples provided in
[Content Security Policy Reference](https://content-security-policy.com/)
#### Other Talisman security considerations
Setting `TALISMAN_ENABLED = True` will invoke Talisman's protection with its default arguments,
of which `content_security_policy` is only one. Those can be found in the
[Talisman documentation](https://pypi.org/project/flask-talisman/) under *Options*.
These generally improve security, but administrators should be aware of their existence.
In particular, the option of `force_https = True` (`False` by default) may break Superset's Alerts & Reports
if workers are configured to access charts via a `WEBDRIVER_BASEURL` beginning
with `http://`. As long as a Superset deployment enforces https upstream, e.g.,
through a load balancer or application gateway, it should be acceptable to keep this
option disabled. Otherwise, you may want to enable `force_https` like this:
```python
TALISMAN_CONFIG = {
"force_https": True,
"content_security_policy": { ...
```
#### Configuring Talisman in Superset
Talisman settings in Superset can be modified using superset_config.py. If you need to adjust security policies, you can override the default configuration.
Example: Overriding Talisman Configuration in superset_config.py for loading images form s3 or other external sources.
```python
TALISMAN_CONFIG = {
"content_security_policy": {
"base-uri": ["'self'"],
"default-src": ["'self'"],
"img-src": [
"'self'",
"blob:",
"data:",
"https://apachesuperset.gateway.scarf.sh",
"https://static.scarf.sh/",
# "https://cdn.brandfolder.io", # Uncomment when SLACK_ENABLE_AVATARS is True # noqa: E501
"ows.terrestris.de",
"aws.s3.com", # Add Your Bucket or external data source
],
"worker-src": ["'self'", "blob:"],
"connect-src": [
"'self'",
"https://api.mapbox.com",
"https://events.mapbox.com",
],
"object-src": "'none'",
"style-src": [
"'self'",
"'unsafe-inline'",
],
"script-src": ["'self'", "'strict-dynamic'"],
},
"content_security_policy_nonce_in": ["script-src"],
"force_https": False,
"session_cookie_secure": False,
}
```
For more information on setting up Talisman, please refer to
https://superset.apache.org/admin-docs/configuration/networking-settings/#changing-flask-talisman-csp.
### Reporting Security Vulnerabilities
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 apprehensions regarding Superset security or you discover vulnerability or potential
threat, dont hesitate to get in touch with the Apache Security Team by dropping a mail at
security@apache.org. In the mail, specify the project name Superset with the description of the
issue or potential threat. You are also urged to recommend the way to reproduce and replicate the
issue. The security team and the Superset community will get back to you after assessing and
analysing the findings.
PLEASE PAY ATTENTION to report the security issue on the security email before disclosing it on
public domain. The ASF Security Team maintains a page with the description of how vulnerabilities
and potential threats are handled, check [their web page](https://apache.org/security/committers.html)
for more details.