安全配置
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
配置设置。这旨在防止直接从 Superset 接口(如 SQL Lab)执行潜在有害的数据库函数或系统变量。
然而,理解以下内容至关重要:
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 permission
权限,则用户只能查看切片或探索已授予他们权限的数据源。 - 数据库:授予对数据库的访问权限允许用户访问该数据库中的所有数据源,并且,如果已向用户授予 SQL Lab 特定的权限,将使用户能够在 SQL Lab 中查询该数据库。
限制对部分数据源的访问
我们建议为用户提供 Gamma 角色以及任何其他可以添加对特定数据源访问权限的角色。我们建议您为每个访问配置文件创建单独的角色。例如,财务团队的用户可能可以访问一组数据库和数据源;这些权限可以整合到一个角色中。具有此配置文件的用户需要被分配 Gamma 角色作为他们可以访问的模型和视图的基础,以及作为数据对象权限集合的财务角色。
一个用户可以关联多个角色。例如,财务团队的一位高管可以被授予 Gamma、Finance 和 Executive 角色。Executive 角色可以提供对仅供高管使用的一组数据源和仪表盘的访问权限。在 Dashboards 视图中,用户只能根据其被赋予的角色和权限查看其有权访问的仪表盘。
行级安全
使用行级安全过滤器(在安全菜单下),您可以创建分配给特定表以及一组角色的过滤器。如果您希望财务团队的成员只能访问 department = "finance"
的行,您可以:
- 使用该子句创建行级安全过滤器(
department = "finance"
) - 然后将该子句分配给 Finance 角色和其适用的表。
子句字段(可以包含任意文本)随后会添加到生成的 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
):控制是否应将 cookie 设置为带有 HttpOnly
标志。
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 安全性有疑虑,或发现漏洞或潜在威胁,请随时通过发送邮件至 security@apache.org 联系 Apache 安全团队。在邮件中,请注明项目名称 Superset,并描述问题或潜在威胁。同时,也请您提供重现和复现问题的方法。安全团队和 Superset 社区将在评估和分析您的发现后回复您。
请注意,在公开披露安全问题之前,务必先通过安全电子邮件报告。ASF 安全团队维护一个页面,描述了如何处理漏洞和潜在威胁,请查看他们的网页了解更多详情。