安全指南

此页面的目标是提供有关如何安全使用 APOC 的指南。不安全地使用 APOC 会导致许多常见的软件漏洞,包括安全配置错误敏感数据泄露服务器端请求伪造语言注入

我们的指南建议采用基于原则的安全事项方法,并分为三个部分。在第一部分中,我们将首先探讨我们的总体原则。在第二部分中,我们将讨论如何在执行查询之前为 APOC 创建安全环境。最后,在第三部分中,我们将介绍如何在查询中安全地使用 APOC。

安全原则

本节介绍的安全原则为安全使用 APOC 提供指导规则。如果遇到此页面未涵盖的任何安全挑战,鼓励用户遵循以下列出的原则。

最小权限原则

也称为最小权限原则,最小权限原则规定工作负载应该只被赋予其操作所需的最小权限集。APOC 提供了广泛的功能,任何给定的 APOC 安装都不太可能全部使用。建议用户仅启用严格需要的那些过程和函数。建议用户禁用任何其他过程和函数。

通过仅启用绝对必要的最低限度,用户将降低运行漏洞过程带来的风险,同时也能支持其功能需求。

纵深防御原则

也称为冗余原则,纵深防御原则规定用户在软件堆栈的每个级别保护其安装,即使这样做似乎是多余的。

APOC 构建在由数据库和操作系统同时公开和控制的接口之上。通过使用纵深防御方法保护 APOC 安装,安装将被包装在多层保护中,从而降低任何一层保护机制发生故障的风险。如果安装受到 APOC、数据库以及操作系统的保护,那么受保护的工作负载不太可能被单个漏洞利用。

安装

本节介绍为 APOC 创建安全环境需要采取的步骤。它关注的是在编写查询之前保护 APOC。

保护 Neo4j

由于APOC提供的功能构建在数据库之上,因此除非数据库安全,否则安装无法保证安全。因此,首要任务是确保数据库安装安全,这可以通过遵循现有的数据库安全检查清单来实现。本指南将更详细地再次回顾检查清单中涵盖的一些步骤。

保护Neo4j扩展

APOC是一个Neo4j扩展,其功能比任何给定工作负载可能需要的都多。与任何Neo4j扩展一样,有一些控制机制可以帮助确保只有必需的功能和过程被安装到数据库中。

通过配置设置保护Neo4j扩展

数据库公开了配置设置,这些设置可以在conf/neo4j.conf配置文件中配置。配置文件控制哪些过程和函数可以加载到数据库中,然后不受限制。控制此行为的配置设置如下所示。

设置 描述 默认值

dbms.security.procedures.allowlist

要加载的功能和过程名称列表。

"*"

dbms.security.procedures.unrestricted

允许完全访问数据库的功能和过程名称列表。

""

建议遵守现有的安装指南,该指南规定了如何加载和取消限制工作负载所需的最小过程集。

通过RBAC保护Neo4j扩展

数据库公开了基于角色的访问控制机制,以微调允许哪些用户角色执行给定操作。这是Neo4j企业版的功能,社区版用户无法使用。

有关用户执行任何给定过程的能力,存在执行过程权限。默认情况下,所有用户都具有以用户自身权限级别执行任何过程的权限。这意味着没有读取权限的用户无法通过过程读取数据,而没有写入权限的用户无法通过过程写入数据。类似的权限也存在于执行函数中。

还存在执行提升过程权限,涉及用户以完全权限执行任何给定过程的能力。这意味着如果授予提升过程权限,则原本不允许读取或写入数据库的用户将被允许这样做。这些权限等同于执行管理员过程权限。类似的权限也存在于执行提升函数中。

执行提升权限是一项强大的功能,有可能被误用。有几个强大的APOC过程能够对数据库运行来自用户输入的整个查询。如果用户被授予以完全权限执行这些过程中的任何一个的提升权限,这相当于赋予用户运行任何Cypher查询的能力。

此类过程的示例包括

建议坚持默认行为,即用户只能以自己的权限级别执行过程和函数,并避免在APOC中执行提升过程。当某个角色需要执行某些操作的权限时,通常可以授予其他权限以实现所需的限制,而无需依赖提升执行。

保护文件系统

APOC包含几个可以读取或写入文件系统上特定文件的过程。如果配置错误,这些过程可能导致高影响漏洞,例如敏感数据泄露。如果工作负载需要,用户需要启用过程才能与文件系统交互,但只能在特定目录中。如果工作负载不需要,用户应该完全限制过程与文件系统交互的能力。

可以从文件系统读取的程序示例包括apoc.load.。可以写入文件系统的程序示例包括apoc.export.。允许数据库从文件系统读取的Cypher子句示例包括LOAD CSV

在操作系统级别保护文件系统

从操作系统的角度来看,只有一个进程正在执行。APOC不作为与数据库进程分开的操作系统进程存在。这意味着应用于数据库的所有操作系统限制也将应用于APOC。因此,文件权限指南为数据库规定的指导也适用于APOC。

建议配置数据库进程,使其仅具有执行工作负载所需的最小文件系统权限集。这意味着限制数据库进程,使其仅在需要时才能与文件系统交互,即使在交互时也只与特定目标目录交互,而不是整个文件系统。

在数据库级别保护文件系统

APOC公开了配置设置,用于控制是否允许与文件系统交互以及从哪个目录交互。这些设置可以在conf/apoc.conf文件中配置,并在下面进行描述。

设置 描述 默认值

apoc.export.file.enabled

启用将文件写入文件系统。

false

apoc.import.file.enabled

启用从文件系统读取文件。

false

apoc.import.file_use_neo4j_config

APOC在读取或写入文件系统时将遵守Neo4j配置设置。

true

数据库还公开了配置设置,用于控制是否允许从文件系统读取文件以及从哪个目录读取。这些设置可以在conf/neo4j.conf文件中配置,并在下面进行描述。

设置 描述 默认值

dbms.security.allow_csv_import_from_file_urls

启用从文件系统读取文件。

false

server.directories.import

将读取文件限制到给定目录。

import

当APOC验证文件系统交互时,它会经过一系列检查。它首先检查是否允许读取或写入。如果是,则检查它可以在其中执行操作的目录。

在确定是否允许读取或写入时,APOC首先验证其自身的配置设置是否已启用,然后检查数据库配置设置是否也已启用。仅当apoc.import.file_use_neo4j_config配置设置已启用时,APOC才会检查数据库配置设置是否也已启用。

在确定允许读取或写入的目录时,APOC会检查apoc.import.file_use_neo4j_config配置设置是否已启用。如果是,它将使用与数据库相同的目录限制。如果未启用此配置设置,则APOC将被允许读取或写入文件系统上的任何位置。

安全指南

建议根据工作负载是否需要读取或写入文件而有所不同。有些工作负载不需要任何文件系统交互,有些只需要数据库能够读取文件,而有些则需要数据库和APOC都能够读取文件。

如果工作负载不需要任何文件系统的读取或写入权限,则用户不应更改任何配置文件中的任何配置设置。默认情况下,Neo4j和APOC查询都不允许读取或写入文件。

如果工作负载只需要数据库能够读取文件,并且不需要APOC能够执行相同的操作,则用户应该只通过设置dbms.security.allow_csv_import_from_file_urls=true来授予数据库此能力。用户不需要对APOC配置设置进行任何修改,因为默认情况下它们不允许APOC读取或写入文件系统中的文件。

如果工作负载需要数据库和APOC都能够读取和写入文件系统,则用户仍然应该尽可能地限制。虽然这将需要在两个配置文件中都启用读取和写入权限,但建议调整APOC配置设置apoc.import.file_use_neo4j_config=true以及Neo4j配置设置server.directories.import=import

用法

上一节提供了在执行查询之前保护APOC安装的指南。本节将提供有关编写包含高风险APOC过程和函数的查询的建议。

Cypher注入

Neo4j知识库提供了关于防止Cypher注入的优秀入门指南,建议学习这些指南,以便更好地了解与Cypher注入相关的挑战。

许多APOC过程直接使用Cypher,在后台,它们将构建和执行从接收到的输入派生的新查询。这些过程对APOC用户提出了额外的挑战,他们需要能够识别它们,并了解它们能够提供的有限安全保证。

在下面的第一个示例中,初始查询调用apoc.uuid.install过程,该过程依次在后台构建第二个查询并执行它。第二个查询获取所有节点,删除一个标签,然后重新附加一个不同的标签。

CALL apoc.uuid.install("Person", {})
// executes a query similar to this: `MATCH (n:Person) SET n.uuid`

在下面的第二个示例中,初始查询调用apoc.cypher.runFile过程,该过程依次在后台构建第二个查询,然后执行它。第二个查询获取所有节点并返回它们。

CALL apoc.cypher.runFile("test.cypher", {})
// executes `MATCH (n) RETURN n`

上述两个示例中的过程都构建并执行从接收到的输入派生的新查询。这两个过程之间的唯一区别是它们接收的输入。在第一个示例中,该过程知道输入表示Cypher字面量。在第二个示例中,该过程知道输入表示整个Cypher查询。第一个示例中的输入可以进行清理,而第二个示例中的输入则不能进行清理。

APOC保证它将清理对应于Cypher字面量的输入。但是,APOC无法为对应于整个Cypher查询的输入提供相同的保证。在后一种情况下,清理Cypher查询的责任委托给用户,建议用户仔细遵循前面提到的Cypher注入指南。

不需要清理的过程示例