除了提供预定义发现类型来检测 SaaS 和云应用程序中的安全问题外,Cloudflare CASB 还允许从零开始定义自定义发现类型,从而完全控制 CASB 检测的安全条件。
- 已添加云或 SaaS 集成。
- 熟悉 Rego ↗。
Cloudflare CASB 提供两种检测安全风险的方式。在 Cloudflare One ↗ 中,它们在 Cloud & SaaS(云和 SaaS) > Findings library(发现库) 中通过 Origin(来源) 值为 "Standard"(标准)或 "Custom"(自定义)来区分。
- 标准发现类型 - 由 Cloudflare CASB 创建和管理的预定义发现类型。可以查看和复制,但不能更改。
- 自定义发现类型 - 在账户中使用 Rego 表达式创建和管理的发现类型。
下表显示 CASB 客户账户对标准和自定义发现类型分别具备的能力:
| 能力 | 标准发现类型 | 自定义发现类型 |
|---|---|---|
| 检查检测逻辑 | ✅ | ✅ |
| 创建态势发现类型 | ❌ | ✅ |
| 创建内容发现类型 | ❌ | ❌ |
| 复制态势发现类型 | ✅ | ✅ |
| 复制内容发现类型 | ❌ | ❌ |
| 编辑态势发现类型 | ❌ | ✅ |
| 编辑内容发现类型 | ❌ | ❌ |
| 删除态势发现类型 | ❌ | ✅ |
| 删除内容发现类型 | ❌ | ❌ |
| 禁用态势发现类型 | ❌ | ❌ |
| 禁用内容发现类型 | ❌ | ❌ |
某家使用 Google Workspace 的公司的安全团队希望了解高管、董事会或法务团队的群组何时对外部人员开放。公司以 exec-、board- 和 legal- 前缀命名这些群组,其中外部法律顾问群组允许有外部成员。由于这取决于公司自身的群组命名约定和例外,CASB 没有针对该精确场景的标准发现类型,因此该团队创建了自定义发现类型。
- 定义发现类型。 在发现库中,团队创建自定义发现类型。他们将其命名为 "Sensitive group open to outsiders"(对外部人员开放的敏感群组),将严重性设置为 High(高),选择 Google Workspace 作为提供商,并编写一条 Rego 表达式:当地址以
exec-、board-或legal-开头的群组允许外部成员(除非是外部法律顾问群组)、允许任何人加入或允许任何人发帖时,返回 "fail"。 - 查看结果。 随着 CASB 收到该公司 Google Workspace 群组的更新,它会评估每一个群组。匹配的群组会作为发现实例出现在 Posture Findings(安全态势发现) 下,以便团队查看哪些敏感群组处于开放状态。其他名称的群组永远不会被标记。
- 采取措施。 团队为此发现类型创建 CASB 策略,向其消息管理自动化系统发送 webhook。之后每个新的发现实例都会触发该自动化以限制该群组。
以下各节详细说明此流程的每个部分。
自定义发现类型包含以下字段:
| 字段 | 描述 |
|---|---|
| Finding Name | 发现类型的显示名称。 |
| Description | 该发现类型检测内容的定义。 |
| Severity | 发现类型的影响:Low、Medium、High 或 Critical。 |
| Provider | 该发现类型检测所针对的集成供应商。 |
| Asset Class | 检测逻辑可用的资产字段集合。这些字段会出现在发现类型构建器的 Available asset fields(可用资产字段) 下。 |
| Category Type | 其生成的发现的分类。 |
| Integrations | CASB 针对此发现类型进行评估的集成。选择 Apply to all integrations(应用于所有集成) 以使用全部集成。 |
| Rego Package | CASB 用于生成发现的检测逻辑。 |
CASB 会在自定义发现类型所配置的集成范围内,于资产创建或更新时对其进行评估。它们不会对现有资产回溯运行。
继续示例场景,一个董事会群组有外部成员,一个新的高管群组对任何人开放:
| 日期 | 事件 | 是否创建发现? |
|---|---|---|
| 星期日 | [email protected] 群组允许外部成员并被更新。 |
否。"Sensitive group open to outsiders" 发现类型尚不存在。 |
| 星期一 | 安全团队创建 "Sensitive group open to outsiders" 发现类型。 | 否。CASB 不会评估 board-directors,因为它自发现类型创建以来没有变更。 |
| 星期二 | [email protected] 群组被创建,且任何人都可以加入。 |
是。CASB 评估该新群组并创建发现实例。 |
| 星期三 | 向 board-directors 添加一名成员。 |
是。CASB 再次评估该群组,并因它仍允许外部成员而创建发现实例。 |
| 星期四 | 允许外部成员的 [email protected] 群组被更新。 |
否。CASB 评估该群组,其结果为 "pass",因为它是已批准的例外,因此不创建发现实例。 |
自定义发现类型使用 Rego ↗ 编写,这是 Open Policy Agent (OPA) 使用的开源策略语言。Rego 入门请参阅 OPA 文档 ↗。CASB 使用 Rego v1,并支持受限制的 Rego 内置函数 ↗和操作子集。
以下表达式是安全团队在示例场景中编写的。它检测对外部人员开放的敏感群组:
sensitive_prefixes := ["exec-", "board-", "legal-"]
external_exceptions := {"[email protected]"}
default result := "pass"
email := lower(input.asset.email)
sensitive if strings.any_prefix_match(email, sensitive_prefixes)
result := "fail" if {
sensitive
input.asset.allowExternalMembers == true
not email in external_exceptions
}
result := "fail" if {
sensitive
input.asset.whoCanJoin == "ANYONE_CAN_JOIN"
}
result := "fail" if {
sensitive
input.asset.whoCanPostMessage == "ANYONE_CAN_POST"
}此表达式的工作方式如下:
sensitive_prefixes和external_exceptions保存公司的值。它们被写入表达式中,因为 CASB 在评估期间无法从另一个系统获取列表。default result := "pass"将每个资产的结果默认设为 "pass",除非表达式中的另一条规则更改它。因此,不匹配的资产永远不会被标记。email := lower(input.asset.email)将群组地址转为小写,因此[email protected]与[email protected]会被同等对待。- 当地址以三个前缀中的任何一个开头时,
sensitive为 true。strings.any_prefix_match一次检查整个列表。其他名称的群组永远不会匹配。 result := "fail" if { ... }在花括号内的所有条件为 true 时将结果改为 "fail"。这将创建发现实例。- 第一条规则检查敏感群组是否在未经明确批准的情况下允许外部成员。
- 第二条规则检查允许任何人加入的敏感群组。
- 第三条规则检查允许任何人发帖的敏感群组。
- 表达式必须定义返回 "pass" 或 "fail" 的
result。"fail" 结果表示资产匹配该发现类型并创建发现实例。 - 添加
default result := "pass",使未匹配失败条件的资产返回 "pass"。 - 无需添加 package 声明或任何 import 语句,包括
import rego.v1。CASB 会自动添加这些内容,编辑器也不会接受它们。 - 可以从
input.asset读取所选资产类别中的字段。 - 某些资产类别包含相关资产,例如文件及其所有者。可用时,通过
input.associated引用相关资产的字段。
在发现类型构建器中选择 Validate(验证),可在创建发现之前检查 Rego 表达式。验证会编译表达式并对照资产架构进行检查。它会报告发现的任何语法错误或不支持的 Rego 内置函数。
验证不会针对数据执行表达式。要确认表达式能检测预期条件,请在创建后验证发现类型的行为。
自定义发现类型支持以下 Rego 内置函数和运算符。未在此列出的任何内置函数均不受支持。
支持的内置函数和运算符
| 类别 | 内置函数 |
|---|---|
| Operators | =, ==, !=, >, >=, <, <=, in |
| Aggregates | count, max, min, product, sort, sum |
| Arrays | array.concat, array.flatten, array.reverse, array.slice |
| Conversion | to_number |
| Encoding and serialization | base64.decode, base64.encode, base64.is_valid, base64url.decode, base64url.encode, base64url.encode_no_pad, hex.decode, hex.encode, json.is_valid, json.marshal, json.marshal_with_options, json.unmarshal, urlquery.decode, urlquery.decode_object, urlquery.encode, urlquery.encode_object |
| Glob and graph | glob.match, glob.quote_meta, graph.reachable, graph.reachable_paths, walk |
| CIDR | net.cidr_contains, net.cidr_contains_matches, net.cidr_intersects, net.cidr_is_valid, net.cidr_merge |
| Numbers | abs, ceil, div, floor, minus, mul, plus, rem, round |
| JSON and objects | json.filter, json.remove, object.filter, object.get, object.keys, object.remove, object.subset, object.union, object.union_n |
| Regular expressions | regex.globs_match, regex.is_valid, regex.match, regex.replace, regex.template_match |
| Semantic versions | semver.compare, semver.is_valid |
| Sets | and, intersection, or, union |
| Strings | concat, contains, endswith, format_int, indexof, indexof_n, lower, replace, split, sprintf, startswith, strings.any_prefix_match, strings.any_suffix_match, strings.count, substring, trim, trim_left, trim_prefix, trim_right, trim_space, trim_suffix, upper |
| Time | time.add_date, time.clock, time.date, time.diff, time.format, time.now_ns, time.parse_duration_ns, time.parse_ns, time.parse_rfc3339_ns, time.weekday |
| Types | is_array, is_boolean, is_null, is_number, is_object, is_set, is_string, type_name |
| Units | units.parse, units.parse_bytes |
| URI | uri.is_valid, uri.parse |
| UUID | uuid.parse, uuid.rfc4122 |
自定义发现类型表达式使用 Rego v1 语法以及本节列出的 Cloudflare 支持的 Rego 内置函数。
- Rego 策略语言 ↗ - Rego 语言文档。
- OPA 内置函数 ↗ - OPA 内置函数的完整列表。自定义发现类型支持其中的子集。
- OPA 风格指南 ↗ - 编写 Rego 表达式的一般指导。
- OPA Playground ↗ - 用于编写和测试一般 Rego 表达式的沙盒。
- 在 Cloudflare One ↗ 中,转到 Cloud & SaaS findings(云和 SaaS 发现) > Findings library(发现库)。
- 选择 Create finding(创建发现)。
- 在 General Information(常规信息) 下,输入发现名称和描述。然后选择严重性。
- 在 Scope Definition(范围定义) 下,选择提供商和资产类别。
- 选择该发现类型应用于该提供商的所有集成,还是选定的集成。
- 在 Detection Logic(检测逻辑) 下,输入 Rego 表达式。使用 Available asset fields(可用资产字段) 识别支持的字段。
- 选择 Validate(验证)。在继续之前解决每个验证错误。
- 选择 Create finding(创建发现)。
CASB 会在所选范围内收到未来的资产更新时应用自定义发现类型。匹配的资产会作为态势发现实例出现。
要确认自定义发现类型正在检测匹配项,请检查其发现实例。
- 在 Cloud & SaaS findings(云和 SaaS 发现) 中,转到 Posture Findings(安全态势发现)。
- 找到该自定义发现类型。
- 查看 Finding Instances(发现实例) 列以确认已找到匹配项。Finding Instances(发现实例) 列显示当前匹配的资产数量。
- 选择 Manage(管理) 以查看匹配的资产。
如果发现类型的集成中已有资产被创建或更新,但仍没有实例出现,请执行以下检查:
- 检查指定的提供商
- 检查指定的资产类别
- 检查指定的集成范围
- 检查已编写的 Rego 表达式中的字段名称
- 检查已编写的 Rego 表达式中使用的字段类型
- 检查已编写的 Rego 表达式的预期输出
- 一个账户最多可以有 250 个自定义发现类型。
- 最多 25 个自定义发现类型可以应用于一个集成。
- 自定义发现类型支持态势发现类型。它们不支持数据丢失预防 (DLP) 内容发现类型。
- 新建和更新的自定义发现类型不会回溯应用。
- 完整的 Rego 策略(包括 Cloudflare 添加的声明)最多可为 4 KiB。
- Rego 表达式评估期间无法进行网络访问。
- 编辑器不接受 package 声明和 import 声明。
自定义发现类型可以像标准发现类型一样用于 CASB 策略。创建策略时,从 Finding type(发现类型) 列表中选择自定义发现类型。
继续前面的示例,安全团队希望每次 CASB 发现对外部人员开放的敏感群组时,都自动限制该群组。
- 创建策略。 团队创建 CASB 策略,并从 Finding type(发现类型) 列表中选择 "Sensitive group open to outsiders"。
- 设置范围。 策略设置为 Apply to all integrations(应用于所有集成),因此它覆盖该发现类型评估的每个 Google Workspace 集成。
- 选择操作。 策略向团队的消息管理自动化系统发送 webhook。
- 查看效果。 当群组被创建或更新且 CASB 将其评估为 "fail" 时,CASB 会创建发现实例。然后策略触发 webhook,自动化会限制该群组的成员资格和发帖设置。
- 自定义发现类型可用于触发 webhook 的策略。
- 策略只能对其所选集成中的发现采取操作,或者在设置了 Apply to all integrations(应用于所有集成) 时对所有集成采取操作。它只能对自定义发现类型集成范围内的集成采取操作。这两个列表不必匹配。
- 如果自定义发现类型的集成范围被编辑以移除某个集成,CASB 不再为该集成创建发现实例,因此策略在那里没有可操作的对象。
- 如果自定义发现类型被隔离,CASB 不会创建新的发现实例,因此策略不会触发。
- 当有策略使用自定义发现类型时,无法删除该发现类型。请先删除策略,然后删除自定义发现类型。
可以复制标准或自定义态势发现类型,可以编辑自定义发现类型上受支持的字段,也可以删除不再需要的自定义发现类型。
打开标准态势发现类型以检查其检测逻辑。如果该逻辑是有用的起点,请复制该发现类型以创建可编辑的副本。
继续前面的示例,领导层要求将高管和董事会群组视为 Critical(严重),且没有例外,而法务群组保持 High(高)。创建后无法编辑严重性,因此安全团队改为复制该发现类型。
- 复制。 团队在 "Sensitive group open to outsiders" 上选择 Duplicate(复制)。CASB 会将名称、描述、严重性、提供商、资产类别、集成范围和 Rego 表达式复制到构建器中。
- 调整。 他们将副本重命名为 "Executive and board group open to outsiders"(对外部人员开放的高管和董事会群组),并将严重性设置为 Critical。在 Rego 表达式中,他们将
sensitive_prefixes改为["exec-", "board-"],并移除external_exceptions以及not email in external_exceptions这一行。 - 创建。 他们选择 Validate(验证),然后选择 Create finding(创建发现)。该副本是一个新的自定义发现类型。
原始的 "Sensitive group open to outsiders" 继续不变地运行。对于这家公司,违反规则的 exec- 或 board- 群组现在会收到两个发现类型的发现,一个为 High,一个为 Critical。
- 在 Cloudflare One ↗ 中,转到 Cloud & SaaS findings(云和 SaaS 发现) > Findings library(发现库)。
- 在发现类型菜单中,选择 Duplicate(复制)。
- 审查复制的名称、描述、严重性、提供商、资产类别、集成范围和 Rego 表达式。
- 根据需要更改复制的字段。
- 选择 Validate(验证)。在继续之前解决每个验证错误。
- 选择 Create finding(创建发现)。
复制的发现类型是一个独立的自定义发现类型。对副本的更改不会影响原始发现类型。
自定义发现类型创建后,只能编辑以下字段:
- 名称
- 描述
- 集成范围
要更改提供商、资产类别、严重性或 Rego 表达式,请复制该发现类型。
- 在 Cloudflare One ↗ 中,转到 Cloud & SaaS findings(云和 SaaS 发现) > Findings library(发现库)。
- 在自定义发现类型菜单中,选择 Edit(编辑)。
- 更新名称、描述或集成范围。
- 选择 Save(保存)。
- 在 Cloudflare One ↗ 中,转到 Cloud & SaaS findings(云和 SaaS 发现) > Findings library(发现库)。
- 在自定义发现类型菜单中,选择 Delete(删除)。
- 确认删除。
删除自定义发现类型将停止对未来资产更新的所有评估,并删除关联的发现实例。
删除发现实例无法撤销。
无法禁用自定义发现类型。要停止 CASB 评估自定义发现类型,请删除它。删除自定义发现类型无法撤销,并且会删除其现有发现实例。
要停止使用自定义发现类型的 CASB 策略触发,请改为关闭该策略。请参阅编辑、关闭或删除策略。
隔离是 CASB 在自定义发现类型的表达式无法被安全评估时应用的状态。
被隔离的自定义发现类型会在 Cloud & SaaS findings(云和 SaaS 发现) > Findings library(发现库) 的条目旁边显示警告图标。
自定义发现类型被隔离期间:
- 现有发现实例仍然可见。
- CASB 在收到资产更新时不会评估该表达式,因此不会创建新的发现实例。
- 同一集成上的其他自定义和标准发现类型继续正常运行。
Policies(策略) 列表不会显示策略何时使用了被隔离的自定义发现类型。
如果 CASB 无法针对资产评估该发现类型,自定义发现类型将被隔离。常见原因包括:
- 对大型数组进行嵌套迭代,例如将列表中的每一项与其他每一项进行比较。
- 针对大型或深度嵌套的资产字段评估时超时。
- 对大型集合中的每个元素运行正则表达式,而更简单的检查(例如
startswith或endswith)就已足够。
Validate(验证) 会编译表达式并对照资产架构进行检查,但不会针对资产数据运行表达式。表达式可以通过验证,稍后仍可能被隔离。
无法从仪表板或 API 手动隔离自定义发现类型,也无法移除该状态。
编辑被隔离自定义发现类型的名称、描述或集成范围不会移除该状态。
无法编辑自定义发现类型表达式。要解决被隔离的自定义发现类型,请复制它并在副本中更正表达式:
- 在 Cloudflare One ↗ 中,转到 Cloud & SaaS findings(云和 SaaS 发现) > Findings library(发现库)。
- 在被隔离的自定义发现类型菜单中,选择 Duplicate(复制)。
- 重写表达式以降低其运行时和内存使用。请参阅自定义发现被隔离的原因。
- 选择 Validate(验证)。在继续之前解决每个验证错误。
- 选择 Create finding(创建发现)。该副本是一个新的自定义发现类型,不会被隔离。
- 如果 CASB 策略 使用了被隔离的自定义发现类型,请将该策略更新为使用新的自定义发现类型。
- 删除被隔离的自定义发现类型。
如果无法确定隔离原因,请联系 Cloudflare 支持。提供自定义发现类型 ID 以及尽可能多的详细信息。
对于 Anthropic AnthropicComplianceRole 资产类别,以下表达式检测具有 Cowork 权限的角色:
default result := "pass"
result := "fail" if {
some permission in input.asset.permissions
permission.action == "cowork"
}对于 Anthropic AnthropicComplianceUser 资产类别,以下表达式检测 example.com 域中的非空电子邮件:
default result := "pass"
result := "fail" if {
input.asset.email != null
regex.match(`(?i)@example\.com$`, input.asset.email)
}对于 Google Workspace GoogleWorkspaceLicenseAssignment 资产类别,以下表达式检测拥有 AI Ultra 许可证的非暂停、非管理员用户:
ai_ultra_sku_id := "1010470008"
default result := "pass"
result := "fail" if {
input.asset.skuId == ai_ultra_sku_id
input.associated.user.isAdmin == false
input.associated.user.isSuspended == false
}