安全配置
Superset 中的认证和授权由 Flask AppBuilder (FAB) 处理,这是一个基于 Flask 构建的应用开发框架。 FAB 提供了认证、用户管理、权限和角色等功能。 请阅读其 安全文档。
内置角色
Superset 自带了一套由 Superset 管理的角色。 你可以假设这些角色会随着 Superset 的发展(以及 Superset 版本的更新)保持最新。
即使 Admin 用户有能力这样做,我们也不建议修改与每个角色关联的权限(例如删除或添加权限)。 当你运行 superset init 命令时(通常在 Superset 版本之间执行), 与每个角色关联的权限将重新同步到它们原始的值。
可以在 /RESOURCES/STANDARD_ROLES.md 中找到这些角色的权限表。
Admin
管理员拥有所有可能的权利,包括授予或撤销其他用户的权利,以及修改其他人的切片和仪表板。
Alpha
Alpha 用户可以访问所有数据源,但他们不能授予或撤销其他用户的访问权限。 他们仅限于修改自己拥有的对象。Alpha 用户可以添加和修改数据源。
Gamma
Gamma 用户访问受限。他们只能消费通过其他补充角色获得访问权限的数据源中的数据。 他们只能查看由他们有访问权限的数据源制作的切片和仪表板。 目前 Gamma 用户无法修改或添加数据源。 我们假设他们主要是内容消费者,尽管他们可以创建切片和仪表板。
另外需要注意的是,当 Gamma 用户查看仪表板和切片列表视图时,他们只会看到自己有访问权限的对象。
sql_lab
sql_lab 角色授予对 SQL Lab 的访问权限。 请注意,虽然 Admin 用户默认可以访问所有数据库, 但 Alpha 和 Gamma 用户需要按数据库逐个授予访问权限。
Public
为了允许未登录用户访问某些 Superset 功能,
你可以使用 PUBLIC_ROLE_LIKE
配置设置,并将其分配给另一个角色,以传递你想要赋予该角色的权限。
例如,在你的 superset_config.py
文件中设置 PUBLIC_ROLE_LIKE = "Gamma"
,就授予公共角色与 Gamma 角色相同的权限集。
这对于启用匿名用户查看仪表板很有用。仍然需要显式授予特定数据集的权限,这意味着你需要编辑 Public 角色并手动将公共数据源添加到角色中。
管理 Gamma 角色的数据源访问权限
以下是仅向用户提供特定数据集访问权限的方法。 首先确保有限访问权限的用户只分配了 Gamma 角色。 其次,创建一个新的角色(Menu -> Security -> List Roles)并点击加号。
这个新窗口允许你为这个新角色命名,将其分配给用户,并在 Permissions 下拉列表中选择表。 要选择与这个角色关联的数据源,只需点击下拉列表并使用搜索框查找你的表名。
然后你可以确认分配给 Gamma 角色的用户是否能看到与你刚刚扩展给他们的表相关的对象(仪表板和切片)。
REST API 用于用户和角色管理
Flask-AppBuilder 支持用户 CRUD 的 REST API, 但此功能处于测试阶段,默认情况下在 Superset 中未启用。 要启用此功能,请在你 的 Superset 配置中设置以下内容:
FAB_ADD_SECURITY_API = True
配置完成后,Swagger 中将显示额外的 "Security" 端点文档供你探索。
自定义权限
FAB 曝露的权限非常细致,允许进行高度定制。 FAB 会为每个创建的模型(can_add、can_delete、can_show、can_edit 等)以及每个视图自动创建许多权限。 除此之外,Superset 还可以曝露更细粒度的权限,如 all_datasource_access。
我们不建议修改这三个基本角色,因为 Superset 是基于一组假设构建的。 不过,你可以创建自己的角色,并将其与现有角色合并。
权限
角色由一组权限组成,Superset 有许多类别的权限。以下是不同类别的权限:
- Model & Action: 模型是实体,如 Dashboard、Slice 或 User。每个模型都有一组固定的权限, 如 can_edit、can_show、can_delete、can_list、can_add 等。 例如,你可以通过向角色添加 Dashboard 实体上的 can_delete 权限 并将此角色授予用户来允许用户删除仪表板。
- Views: 视图是个别 web 页,如 Explore 视图或 SQL Lab 视图。 当授予用户时,他们将在菜单项中看到该视图,并能够加载该页面。
- Data source: 对于每个数据源,都会创建一个权限。
如果用户没有被授予
all_datasource_access
权限, 则用户只能看到他们被授予的数据源的 Slices 或 explore 数据源。 - Database: 授予对数据库的访问权限允许用户访问该数据库中的所有数据源, 并且如果已授予用户 SQL Lab 的特定权限,则用户可以在 SQL Lab 中查询该数据库。
限制对子集数据源的访问
我们建议给用户分配 Gamma 角色加上任何增加特定数据源访问权限的其他角色。 我们建议为每个访问配置文件创建单独的角色。 例如,财务团队的用户可能有权访问一组数据库和数据源; 这些权限可以整合在一个角色中。 具有这种配 置文件的用户需要被分配 Gamma 角色作为他们可以访问的模型和视图的基础, 以及包含对数据对象权限的财务(Finance)角色。
用户可以拥有多个关联的角色。例如,财务团队的高管可以 被授予 Gamma、Finance 和 Executive 角色。 Executive 角色可以提供对仅对高管开放的一组数据源和仪表板的访问。 在 Dashboards 视图中,用户只能看到他们有权访问的那些仪表板。
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
行级安全性
使用行级安全性过滤器(在 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 被标记为“安全”的情况下通过 HTTPS 请求发送 Cookie。对于此设置有意义,应用程序必须通过 HTTPS 提供服务。
SESSION_COOKIE_SAMESITE
: (默认:"Lax")防止浏览器将此 Cookie 与跨站请求一起发送。
PERMANENT_SESSION_LIFETIME
: (默认:"31 天")永久会话的生命周期作为一个 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
以禁用 CSPTALISMAN_CONFIG
包含实际的策略定义(见下面的例子)以及其他传递给 Talisman 的参数。
在生产模式下运行时,Superset 将在启动时检查是否存在 CSP。
如果没有找到 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> -
一些仪表板使用 data URI 加载图像,因此需要在
img-src
中包含data:
。img-src 'self' data:
-
MapBox 图表使用 worker 并需要连接到 MapBox 服务器以及 Superset 的来源。
worker-src 'self' blob:
connect-src 'self' https://api.mapbox.com https://events.mapbox.com -
其他 CSP 指令默认为
'self'
以限制内容仅限于与 Superset 服务器相同的来源。
为了根据你的需求调整提供的 CSP 配置, 请遵循 内容安全策略参考 中提供的说明和示例。
其他 Talisman 安全考虑
设置 TALISMAN_ENABLED = True
将 启用 Talisman 的保护及其默认参数,
其中 content_security_policy
只是其中之一。
这些参数可以在 Talisman 文档
的 Options 部分找到。这些设置通常会提高安全性,但管理员应该了解它们的存在。
特别是,force_https = True
(默认为 False
)可能会破坏 Superset 的警报和报告功能,
如果工作进程被配置为通过以 http://
开头的 WEBDRIVER_BASEURL
访问图表。
只要 Superset 部署在上游强制使用 https,例如,通过负载均衡器或应用网关,
则可以接受禁用此选项。否则,你可能想要像这样启用 force_https
:
TALISMAN_CONFIG = {
"force_https": True,
"content_security_policy": { ...
报告安全漏洞
Apache 软件基金会对其软件项目中的安全问题采取严格的立场。 Apache Superset 对其特性和功能相关的安全问题高度敏感并积极应对。
如果你对 Superset 的安全性有所顾虑,或者发现漏洞或潜在威胁, 请毫不犹豫地通过发送邮件至 security@apache.org 与 Apache 安全团队联系。 在邮件中,请指定项目名称 Superset 并附上问题或潜在威胁的描述。 你也被鼓励提供重现问题的方法。安全团队和 Superset 社区将在评估和分析发现后回复你。
请注意 在公开披露之前先通过安全邮箱报告安全问题。 ASF 安全团队维护了一个页面,详细描 述了如何处理漏洞和潜在威胁, 请访问 他们的网页 获取更多详情。