安全配置
Superset 中的身份验证和授权由 Flask AppBuilder (FAB) 处理,FAB 是一个基于 Flask 构建的应用程序开发框架。FAB 提供身份验证、用户管理、权限和角色。请阅读其 安全文档。
提供的角色
Superset 附带一组由 Superset 本身处理的角色。您可以假设这些角色将随着 Superset 的发展(以及您更新 Superset 版本)保持最新。
尽管 Admin 用户有能力,但我们不建议更改与每个角色相关的权限(例如,通过删除或添加权限)。当您运行 superset init 命令(通常在 Superset 版本之间执行)时,与每个角色相关的权限将重新同步到其原始值。
这些角色的权限表可在 /RESOURCES/STANDARD_ROLES.md 找到。
管理员
管理员拥有所有可能的权限,包括授予或撤销其他用户的权限以及修改其他人的切片和仪表板。
Alpha
Alpha 用户可以访问所有数据源,但他们不能授予或撤销其他用户的访问权限。他们还仅限于修改自己拥有的对象。Alpha 用户可以添加和修改数据源。
Gamma
Gamma 用户的访问权限有限。他们只能使用通过另一个补充角色授予他们访问权限的数据源中的数据。他们只能查看由他们有权访问的数据源制作的切片和仪表板。目前,Gamma 用户无法修改或添加数据源。我们假设他们主要是内容消费者,尽管他们可以创建切片和仪表板。
另请注意,当 Gamma 用户查看仪表板和切片列表视图时,他们将只看到他们有权访问的对象。
sql_lab
sql_lab 角色授予对 SQL Lab 的访问权限。请注意,虽然 Admin 用户默认可以访问所有数据库,但 Alpha 和 Gamma 用户都需要按数据库授予访问权限。
公共
要允许注销用户访问某些 Superset 功能,您可以使用 `PUBLIC_ROLE_LIKE` 配置设置,并将其分配给另一个角色,您希望将该角色的权限传递给此角色。
例如,通过在 `superset_config.py` 文件中设置 `PUBLIC_ROLE_LIKE = "Gamma"`,您授予公共角色与 Gamma 角色相同的权限集。如果有人希望启用匿名用户查看仪表板,这很有用。仍需要明确授予特定数据集的权限,这意味着您需要编辑 Public 角色并手动将公共数据源添加到该角色。
管理 Gamma 角色的数据源访问
以下是如何只向用户提供对特定数据集的访问权限。首先,确保对访问权限受限的用户只分配了 Gamma 角色。其次,创建一个新角色(菜单 -> 安全 -> 列出角色),然后点击 + 号。
这个新窗口允许您为这个新角色命名,将其分配给用户,并在权限下拉菜单中选择表。要选择要与此角色关联的数据源,只需点击下拉菜单并使用预输入搜索您的表名。
然后,您可以向分配了 Gamma 角色的用户确认他们看到了与您刚刚扩展的表关联的对象(仪表板和切片)。
SQL 执行安全注意事项
Apache Superset 包含旨在在与连接的数据库交互时提供保障的功能,例如 `DISALLOWED_SQL_FUNCTIONS` 配置设置。这旨在防止直接从 SQL Lab 等 Superset 界面执行潜在有害的数据库函数或系统变量。
但是,理解以下内容至关重要:
Superset 不是数据库防火墙:Superset 的内置检查(例如 `DISALLOWED_SQL_FUNCTIONS`)提供了一层保护,但不能保证完全防御所有数据库级别的威胁或高级绕过技术(例如特定的注释注入方法)。它们应被视为对强大的数据库安全的补充,而不是替代。
配置是关键:Superset 安全措施的有效性严重依赖于 Superset 管理员的正确配置。这包括维护 `DISALLOWED_SQL_FUNCTIONS` 列表、仔细管理功能标志(例如 `ENABLE_TEMPLATE_PROCESSING`)以及适当配置其他安全设置。
数据库安全至关重要:保护数据库访问、控制权限和防止未经授权的函数执行的最终责任在于管理底层数据库实例的数据库管理员 (DBA) 和安全团队。
推荐的数据库实践:我们强烈建议在数据库级别实施安全最佳实践,包括:
- 最小权限:使用具有 Superset 操作所需最小权限的专用数据库用户帐户连接 Superset(通常是对必要模式/表的只读访问)。
- 数据库角色和权限:利用数据库原生角色和权限来限制对敏感函数、系统变量(例如 `@@hostname`)、模式或表的访问。
- 网络安全:采用数据库防火墙或代理等网络级控制来限制连接。
- 审计:启用数据库级审计以监控执行的查询和访问模式。
通过将 Superset 的可配置安全措施与强大的数据库级安全实践相结合,您可以实现更强大和分层的安全态势。
用于用户和角色管理的 REST API
Flask-AppBuilder 支持用于用户 CRUD 的 REST API,但此功能处于测试阶段,默认情况下在 Superset 中未启用。要启用此功能,请在 Superset 配置中进行以下设置
FAB_ADD_SECURITY_API = True
配置完成后,Swagger 中将显示其他“安全”端点的文档供您探索。
自定义权限
FAB 公开的权限非常细粒度,允许高度定制。FAB 会为创建的每个模型(can_add、can_delete、can_show、can_edit 等)以及每个视图自动创建许多权限。除此之外,Superset 可以公开更细粒度的权限,例如 all_datasource_access。
我们不建议修改 3 个基本角色,因为 Superset 基于一组假设构建。但您可以创建自己的角色,并将它们合并到现有角色中。
权限
角色由一组权限组成,Superset 有许多权限类别。以下是不同的权限类别
- 模型和操作:模型是像仪表板、切片或用户这样的实体。每个模型都有一组固定的权限,例如 can_edit、can_show、can_delete、can_list、can_add 等等。例如,您可以通过向角色添加仪表板实体的 can_delete 权限并将该角色授予用户来允许用户删除仪表板。
- 视图:视图是单独的网页,例如探索视图或 SQL Lab 视图。当授予用户时,他们将在其菜单项中看到该视图,并能够加载该页面。
- 数据源:为每个数据源创建权限。如果用户没有被授予 `all_datasource_access` 权限,则用户只能查看切片或探索已授予他们的数据源
- 数据库:授予对数据库的访问权限允许用户访问该数据库中的所有数据源,并且,如果已向用户授予 SQL Lab 特定权限,则用户将能够在 SQL Lab 中查询该数据库
限制对数据源子集的访问
我们建议为用户提供 Gamma 角色以及其他任何可以添加特定数据源访问权限的角色。我们建议您为每个访问配置文件创建单独的角色。例如,财务团队的用户可能可以访问一组数据库和数据源;这些权限可以整合到一个角色中。然后,具有此配置文件的用户需要被分配 Gamma 角色作为他们可以访问的模型和视图的基础,以及作为数据对象权限集合的财务角色。
一个用户可以关联多个角色。例如,财务团队的某个主管可以被授予 Gamma、Finance 和 Executive 角色。Executive 角色可以提供对一组仅限主管访问的数据源和仪表板的访问。在 Dashboards 视图中,用户只能根据分配的角色和权限查看他们有权访问的仪表板。
行级安全
使用行级安全过滤器(在 Security 菜单下),您可以创建分配给特定表以及一组角色的过滤器。如果您希望财务团队的成员只能访问 `department = "finance"` 的行,您可以
- 创建一个包含该子句的行级安全过滤器 (`department = "finance"`)。
- 然后将该子句分配给 Finance 角色及其适用的表。
然后,包含任意文本的 clause 字段将添加到生成的 SQL 语句的 WHERE 子句中。因此,您甚至可以创建一个用于过去 30 天的过滤器并将其应用于特定角色,子句为 `date_field > DATE_SUB(NOW(), INTERVAL 30 DAY)`。它还可以支持多个条件:`client_id = 6` AND `advertiser="foo"` 等。
所有相关的行级安全过滤器将组合在一起(在底层,不同的 SQL 子句使用 AND 语句组合)。这意味着可能会出现两个角色冲突的情况,从而将表子集限制为空。
例如,过滤器 `client_id=4` 和 `client_id=5` 应用到一个角色,将导致该角色的用户在查询中添加 `client_id=4` AND `client_id=5`,这永远不可能为真。
用户会话
Superset 使用 Flask 和 Flask-Login 进行用户会话管理。
会话 cookie 用于维护请求之间的会话信息和用户状态,尽管它们不包含个人用户信息,但它们的作用是识别服务器端的用户会话。会话 cookie 使用应用程序的 `SECRET_KEY` 加密,客户端无法读取。因此,保守 `SECRET_KEY` 的秘密并将其设置为一个安全的唯一复杂随机值非常重要。
Flask 和 Flask-Login 提供了许多配置选项来控制会话行为。
- 相关 Flask 设置
`SESSION_COOKIE_HTTPONLY`:(默认值:`False`):控制是否使用 `HttpOnly` 标志设置 cookie。
`SESSION_COOKIE_SECURE`:(默认值:`False`)如果 cookie 被标记为“secure”,浏览器将仅通过 HTTPS 发送带有请求的 cookie。应用程序必须通过 HTTPS 提供服务才能使其有意义。
`SESSION_COOKIE_SAMESITE`:(默认值:“Lax”)阻止浏览器将此 cookie 与跨站请求一起发送。
`PERMANENT_SESSION_LIFETIME`:(默认值:“31 days”)永久会话的生命周期,以 `datetime.timedelta` 对象表示。
切换到服务器端会话
服务器端会话在安全性和性能方面优于客户端会话。通过启用服务器端会话,会话数据存储在服务器端,并且只有会话 ID 发送给客户端。当用户登录时,服务器端会创建一个会话,并将该会话 ID 以 cookie 的形式发送给客户端。客户端将在每次请求时发送会话 ID,服务器将使用它来检索会话数据。注销时,会话在服务器端销毁,并且客户端上的会话 cookie 被删除。这降低了重放攻击和会话劫持的风险。
Superset 使用 Flask-Session 来管理服务器端会话。要启用此扩展,您必须设置
SESSION_SERVER_SIDE = True
Flask-Session 为 Flask 提供了多种后端会话接口,以下是 Redis 的一个示例
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
内容安全策略 (CSP)
Superset 使用 Talisman 扩展来启用 内容安全策略 (CSP) 的实施,这是一个额外的安全层,有助于检测和缓解某些类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击。
CSP 使服务器管理员能够通过指定浏览器应视为可执行脚本的有效来源的域来减少或消除 XSS 发生的向量。然后,兼容 CSP 的浏览器将只执行从这些允许域接收的源文件中加载的脚本,忽略所有其他脚本(包括内联脚本和事件处理 HTML 属性)。
策略通过一系列策略指令来描述,每个指令描述特定资源类型或策略区域的策略。您可以在此处查看可能的指令。
在部署 Superset 时正确配置内容安全策略以防止多种类型的攻击至关重要。Superset 在 `config.py` 中提供了两个变量用于部署 CSP
- `TALISMAN_ENABLED` 默认为 `True`;将其设置为 `False` 以禁用 CSP。
- `TALISMAN_CONFIG` 包含实际的策略定义(参见下面的示例)以及要传递给 Talisman 的任何其他参数。
在生产模式下运行时,Superset 将在启动时检查 CSP 的存在。如果未找到,它将发出带有安全风险的警告。对于使用其他软件在 Superset 外部定义 CSP 策略的环境,管理员可以使用 `config.py` 中的 `CONTENT_SECURITY_POLICY_WARNING` 键禁用此警告。
CSP 要求
-
Superset 需要 `style-src unsafe-inline` CSP 指令才能运行。
style-src 'self' 'unsafe-inline' -
只有带有 nonce 标记的脚本才能加载和执行。Nonce 是 Talisman 在每次页面加载时自动生成的随机字符串。您可以通过调用 jinja 宏 `csp_nonce()` 获取当前 nonce 值。
<script nonce="{{ csp_nonce() }}">
/* my script */
</script> -
一些仪表板使用数据 URI 加载图片,并且在它们的 `img-src` 中需要 `data:`
img-src 'self' data: -
MapBox 图表使用 Worker,除了 Superset 源之外,还需要连接到 MapBox 服务器。
worker-src 'self' blob:
connect-src 'self' https://api.mapbox.com https://events.mapbox.com -
Cartodiagram 图表从外部资源请求地图数据(图像和 JSON),这些资源可以由用户编辑,因此需要一个允许请求的域列表或 `img-src` 和 `connect-src` 的通配符 (`'*'`)。
-
其他 CSP 指令默认为 `'self'`,以将内容限制为与 Superset 服务器相同的来源。
为了根据您的需要调整提供的 CSP 配置,请遵循 内容安全策略参考 中提供的说明和示例。
其他 Talisman 安全注意事项
将 `TALISMAN_ENABLED = True` 设置为 `True` 将会使用 Talisman 的默认参数启用其保护,其中 `content_security_policy` 只是其中之一。这些参数可以在 Talisman 文档 的 选项 部分找到。这些通常会提高安全性,但管理员应该了解它们的存在。
特别是,`force_https = True`(默认为 `False`)选项可能会破坏 Superset 的警报和报告功能,如果 worker 配置为通过以 `http://` 开头的 `WEBDRIVER_BASEURL` 访问图表。只要 Superset 部署强制上游使用 https(例如,通过负载均衡器或应用程序网关),保持此选项禁用应该是可以接受的。否则,您可能需要像这样启用 `force_https`
TALISMAN_CONFIG = {
"force_https": True,
"content_security_policy": { ...
在 Superset 中配置 Talisman
Superset 中的 Talisman 设置可以通过 superset_config.py 进行修改。如果您需要调整安全策略,可以覆盖默认配置。
示例:在 superset_config.py 中覆盖 Talisman 配置以加载 s3 或其他外部源的图像。
TALISMAN_CONFIG = {
"content_security_policy": {
"base-uri": ["'self'"],
"default-src": ["'self'"],
"img-src": [
"'self'",
"blob:",
"data:",
"https://apachesuperset.gateway.scarf.sh",
"https://#/",
# "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,
}
有关设置 Talisman 的更多信息,请参阅 https://superset.apache.org/docs/configuration/networking-settings/#changing-flask-talisman-csp。
报告安全漏洞
Apache 软件基金会在消除其软件项目中的安全问题方面采取了严格的立场。Apache Superset 对与其特性和功能相关的安全问题高度敏感和乐于配合。
如果您对 Superset 安全有疑虑,或者您发现漏洞或潜在威胁,请立即联系 Apache 安全团队,发送邮件至 security@apache.org。在邮件中,请指定项目名称 Superset,并描述问题或潜在威胁。我们还敦促您推荐重现和复制问题的方法。安全团队和 Superset 社区将在评估和分析结果后与您联系。
请务必在公开披露安全问题之前,先通过安全邮箱报告。ASF 安全团队维护一个页面,其中描述了如何处理漏洞和潜在威胁,请访问 他们的网页 以获取更多详细信息。