{{< details >}}
- Tier: 旗舰版
- Offering: JihuLab.com, 私有化部署
{{< /details >}}
{{< history >}}
- 在极狐GitLab 16.2 中,支持指定不明确的 passthrough 引用
{{< /history >}}
您可以通过在被扫描的存储库中定义规则集配置文件来自定义我们的 SAST 分析器的行为。有两种类型的自定义:
- 修改预定义规则的行为。这包括:
- 禁用预定义规则。适用于所有分析器。
- 覆盖预定义规则的元数据。适用于所有分析器。
- 通过使用passthroughs构建自定义配置来替换预定义规则。仅适用于基于 Semgrep 的分析器。
极狐GitLab 高级 SAST 仅支持修改预定义规则的行为,不支持替换预定义规则。
禁用预定义规则
您可以为任何 SAST 分析器禁用预定义规则。
当您禁用规则时:
- 大多数分析器仍然会扫描漏洞。结果在扫描完成后作为处理步骤被移除,并且不会出现在
gl-sast-report.json
产物中。 - 禁用规则的发现结果不再显示在流水线安全选项卡中。
- 默认分支上的禁用规则的现有发现结果在漏洞报告中标记为
不再检测
。
基于 Semgrep 的分析器处理禁用规则的方式不同:
- 为了提高性能,基于 Semgrep 的分析器根本不扫描禁用规则。
- 如果您在基于 Semgrep 的分析器中禁用规则,当您将
sast-ruleset.toml
文件合并到默认分支后,该规则的现有漏洞发现会自动解决。
覆盖预定义规则的元数据
您可以为任何 SAST 分析器覆盖预定义规则的某些属性。这在适应 SAST 到您的现有工作流程或工具时可能很有用。例如,您可能希望根据组织政策覆盖漏洞的严重性,或选择在漏洞报告中显示不同的消息。
构建自定义配置
您可以用自己的规则替换极狐GitLab 维护的规则集用于基于 Semgrep 的分析器。
您通过 passthroughs 提供您的自定义,这些 passthroughs 在运行时被组成一个 passthrough 链并评估以生成完整的配置。然后根据这个新配置执行基础扫描仪。
有多种 passthrough 类型可以让您以不同的方式提供配置,例如使用提交到您的存储库中的文件或在规则集配置文件中内联。您还可以选择如何处理链中的后续 passthrough;它们可以覆盖或附加到先前的配置。
创建配置文件
要创建规则集配置文件:
- 在项目的根目录创建一个
.gitlab
目录,如果不存在的话。 - 在
.gitlab
目录中创建一个名为sast-ruleset.toml
的文件。
指定远程配置文件
{{< history >}}
- 引入于极狐GitLab 16.1。
{{< /history >}}
您可以设置一个CI/CD 变量来使用存储在当前存储库之外的规则集配置文件。这可以帮助您在多个项目中应用相同的规则。
SAST_RULESET_GIT_REFERENCE
变量使用与Git URLs类似的格式来指定项目 URI、可选认证和可选 Git SHA。该变量使用以下格式:
[<AUTH_USER>[:<AUTH_PASSWORD>]@]<PROJECT_PATH>[@<GIT_SHA>]
{{< alert type=”note” >}}
如果项目有一个 .gitlab/sast-ruleset.toml
文件被提交,那么该本地配置优先,并且不使用 SAST_RULESET_GIT_REFERENCE
中的文件。
{{< /alert >}}
以下示例启用 SAST并使用共享的规则集自定义文件。在这个示例中,该文件在 example-ruleset-project
的默认分支上提交,路径为 .gitlab/sast-ruleset.toml
。
include:
- template: Jobs/SAST.gitlab-ci.yml
variables:
SAST_RULESET_GIT_REFERENCE: "gitlab.com/example-group/example-ruleset-project"
有关高级用法,请参见指定私有远程配置示例。
远程配置文件故障排除
如果远程配置文件似乎没有正确应用自定义,原因可能是:
- 您的存储库有一个本地
.gitlab/sast-ruleset.toml
文件。- 默认情况下,如果本地文件存在,则使用本地文件,即使设置了远程配置作为变量。
- 您可以将SECURE_ENABLE_LOCAL_CONFIGURATION CI/CD 变量设置为
false
来忽略本地配置文件。
- 认证有问题。
- 要检查这是否是问题的原因,请尝试引用不需要认证的存储库位置的配置文件。
模式
顶级部分
顶级部分包含一个或多个_配置部分_,定义为 TOML 表。
设置 | 描述 |
---|---|
[$analyzer] |
为分析器声明一个配置部分。名称遵循SAST 分析器列表中定义的名称。 |
配置示例:
[semgrep]
...
避免创建修改现有规则_并且_构建自定义规则集的配置部分,因为后者完全替换预定义规则。
[$analyzer]
配置部分
[$analyzer]
部分允许您自定义分析器的行为。有效属性基于您正在进行的配置类型而有所不同。
设置 | 适用范围 | 描述 |
---|---|---|
[[$analyzer.ruleset]] |
预定义规则 | 定义对现有规则的修改。 |
interpolate |
所有 | 如果设置为 true ,您可以在配置中使用 $VAR 来评估环境变量。使用此功能时请谨慎,以免泄露密钥或令牌。(默认值:false ) |
description |
Passthroughs | 自定义规则集的描述。 |
targetdir |
Passthroughs | 最终配置应持久化的目录。如果为空,则创建一个随机名称的目录。目录最多可包含 100 MB 的文件。如果 SAST 作业以非 root 用户权限运行,请确保活动用户对该目录具有读取和写入权限。 |
validate |
Passthroughs | 如果设置为 true ,则验证每个 passthrough 的内容。验证适用于 yaml 、xml 、json 和 toml 内容。根据 [[$analyzer.passthrough]] 部分中的 target 参数使用的扩展名识别正确的验证器。(默认值:false ) |
timeout |
Passthroughs | 在超时之前评估 passthrough 链的最大时间。超时不能超过 300 秒。(默认值:60) |
interpolate
{{< alert type=”warning” >}}
为了减少泄露密钥的风险,请谨慎使用此功能。
{{< /alert >}}
下面的示例显示了使用 $GITURL
环境变量访问私有存储库的配置。变量包含用户名和令牌(例如 https://user:token@url
),因此它们不会显式存储在配置文件中。
[semgrep]
description = "我的私有 Semgrep 规则集"
interpolate = true
[[semgrep.passthrough]]
type = "git"
value = "$GITURL"
ref = "main"
[[$analyzer.ruleset]]
部分
[[$analyzer.ruleset]]
部分针对并修改单个预定义规则。您可以为每个分析器定义一个到多个这些部分。
设置 | 描述 |
---|---|
disable |
规则是否应禁用。(默认值:false ) |
[$analyzer.ruleset.identifier] |
选择要修改的预定义规则。 |
[$analyzer.ruleset.override] |
定义规则的覆盖。 |
配置示例:
[semgrep]
[[semgrep.ruleset]]
disable = true
...
[$analyzer.ruleset.identifier]
部分
[$analyzer.ruleset.identifier]
部分定义您希望修改的预定义规则的标识符。
设置 | 描述 |
---|---|
type |
预定义规则使用的标识符类型。 |
value |
预定义规则使用的标识符值。 |
您可以通过查看分析器生成的gl-sast-report.json
来查找 type
和 value
的正确值。您可以从分析器的 CI 作业下载该文件作为作业产物。
例如,下面的代码片段显示了来自 semgrep
规则的一个发现,其中包含三个标识符。JSON 对象中的 type
和 value
键对应于您应在此部分中提供的值。
...
"vulnerabilities": [
{
"id": "7331a4b7093875f6eb9f6eb1755b30cc792e9fb3a08c9ce673fb0d2207d7c9c9",
"category": "sast",
"message": "Key Exchange without Entity Authentication",
"description": "Audit the use of ssh.InsecureIgnoreHostKey\n",
...
"identifiers": [
{
"type": "semgrep_id",
"name": "gosec.G106-1",
"value": "gosec.G106-1"
},
{
"type": "cwe",
"name": "CWE-322",
"value": "322",
"url": "https://cwe.mitre.org/data/definitions/322.html"
},
{
"type": "gosec_rule_id",
"name": "Gosec Rule ID G106",
"value": "G106"
}
]
}
...
]
...
配置示例:
[semgrep]
[[semgrep.ruleset]]
[semgrep.ruleset.identifier]
type = "semgrep_id"
value = "gosec.G106-1
...
[$analyzer.ruleset.override]
部分
[$analyzer.ruleset.override]
部分允许您覆盖预定义规则的属性。
设置 | 描述 |
---|---|
description |
议题的详细描述。 |
message |
(已弃用)议题的描述。 |
name |
规则的名称。 |
severity |
规则的严重性。有效选项是:Critical , High , Medium , Low , Unknown , Info
|
{{< alert type=”note” >}}
虽然 message
由分析器填充,但它已被弃用,取而代之的是 name
和 description
。
{{< /alert >}}
配置示例:
[semgrep]
[[semgrep.ruleset]]
[semgrep.ruleset.override]
severity = "Critical"
name = "命令注入"
...
[[$analyzer.passthrough]]
部分
{{< alert type=”note” >}}
Passthrough 配置仅适用于基于 Semgrep 的分析器。
{{< /alert >}}
[[$analyzer.passthrough]]
部分允许您为分析器构建自定义配置。您可以为每个分析器定义最多 20 个这些部分。Passthroughs 被组成一个_passthrough 链_,该链评估为一个完整配置,替换分析器的预定义规则。
Passthroughs 按顺序评估。在链中稍后的 passthroughs 具有更高的优先级,并且可以覆盖或附加到之前 passthroughs 生成的数据(取决于 mode
)。这对于需要使用或修改现有配置的情况很有用。
单个 passthrough 生成的配置大小限制为 10 MB。
设置 | 适用范围 | 描述 |
---|---|---|
type |
所有 |
file 、raw 、git 或 url 中的一个。 |
target |
所有 | 目标文件包含 passthrough 评估写入的数据。如果为空,则使用随机文件名。 |
mode |
所有 | 如果 overwrite ,则 target 文件被覆盖。如果 append ,则新内容附加到 target 文件。git 类型仅支持 overwrite 。(默认值:overwrite ) |
ref |
type = "git" |
包含要拉取的分支、标签或 SHA 的名称 |
subdir |
type = "git" |
用于选择 Git 存储库的子目录作为配置源。 |
value |
所有 | 对于 file 、url 和 git 类型,定义文件或 Git 存储库的位置。对于 raw 类型,包含内联配置。 |
validator |
所有 | 用于在 passthrough 评估后显式调用目标文件上的验证器(xml 、yaml 、json 、toml )。 |
Passthrough 类型
类型 | 描述 |
---|---|
file |
使用 Git 存储库中存在的文件。 |
raw |
内联提供配置。 |
git |
从远程 Git 存储库拉取配置。 |
url |
使用 HTTP 获取配置。 |
{{< alert type=”warning” >}}
当使用带有 YAML 片段的 raw
passthrough 时,建议将 sast-ruleset.toml
文件中的所有缩进格式化为空格。YAML 规范要求使用空格而不是制表符,除非缩进以相应的方式表示,否则分析器无法解析您的自定义规则集。
{{< /alert >}}
示例
禁用预定义的极狐GitLab 高级 SAST 规则
您可以禁用极狐GitLab 高级 SAST 规则或编辑其元数据。以下示例根据不同的标准禁用规则:
- CWE 标识符,它标识整个漏洞类别。
- 极狐GitLab 高级 SAST 规则 ID,它标识在极狐GitLab 高级 SAST 中使用的特定检测策略。
- 关联的 Semgrep 规则 ID,它包含在极狐GitLab 高级 SAST 发现中以实现兼容性。此附加元数据允许在两个分析器在同一位置创建相似发现时自动转换发现。
这些标识符显示在每个漏洞的漏洞详细信息中。您还可以在可下载的 SAST 报告产物中看到每个标识符及其关联的 type
。
[gitlab-advanced-sast]
[[gitlab-advanced-sast.ruleset]]
disable = true
[gitlab-advanced-sast.ruleset.identifier]
type = "cwe"
value = "89"
[[gitlab-advanced-sast.ruleset]]
disable = true
[gitlab-advanced-sast.ruleset.identifier]
type = "gitlab-advanced-sast_id"
value = "java-spring-csrf-unrestricted-requestmapping-atomic"
[[gitlab-advanced-sast.ruleset]]
disable = true
[gitlab-advanced-sast.ruleset.identifier]
type = "semgrep_id"
value = "java_cookie_rule-CookieHTTPOnly"
禁用其他 SAST 分析器的预定义规则
通过以下自定义规则集配置,以下规则从报告中省略:
-
semgrep
规则具有semgrep_id
为gosec.G106-1
或cwe
为322
。 -
sobelow
规则具有sobelow_rule_id
为sql_injection
。 -
flawfinder
规则具有flawfinder_func_name
为memcpy
。
[semgrep]
[[semgrep.ruleset]]
disable = true
[semgrep.ruleset.identifier]
type = "semgrep_id"
value = "gosec.G106-1"
[[semgrep.ruleset]]
disable = true
[semgrep.ruleset.identifier]
type = "cwe"
value = "322"
[sobelow]
[[sobelow.ruleset]]
disable = true
[sobelow.ruleset.identifier]
type = "sobelow_rule_id"
value = "sql_injection"
[flawfinder]
[[flawfinder.ruleset]]
disable = true
[flawfinder.ruleset.identifier]
type = "flawfinder_func_name"
value = "memcpy"
覆盖预定义规则元数据
通过以下自定义规则集配置,使用 semgrep
发现的漏洞,类型为 CWE
,值为 322
的漏洞,其严重性被覆盖为 Critical
。
[semgrep]
[[semgrep.ruleset]]
[semgrep.ruleset.identifier]
type = "cwe"
value = "322"
[semgrep.ruleset.override]
severity = "Critical"
使用文件 passthrough 为 semgrep
构建自定义配置
通过以下自定义规则集配置,semgrep
分析器的预定义规则集被存储库中包含的名为 my-semgrep-rules.yaml
的文件中的自定义规则集替换。
# my-semgrep-rules.yml
---
rules:
- id: my-custom-rule
pattern: print("Hello World")
message: |
Unauthorized use of Hello World.
severity: ERROR
languages:
- python
[semgrep]
description = "我的 Semgrep 自定义规则集"
[[semgrep.passthrough]]
type = "file"
value = "my-semgrep-rules.yml"
使用 passthrough 链为 semgrep
构建自定义配置
通过以下自定义规则集配置,semgrep
分析器的预定义规则集被评估为四个 passthrough 组成的链生成的自定义规则集替换。每个 passthrough 生成一个文件,写入到容器内的 /sgrules
目录中。设置了 60 秒的 timeout
以防任何 Git 远程无响应。
这个示例中展示了不同的 passthrough 类型:
- 两个
git
passthrough,第一个从myrules
Git 存储库拉取develop
分支,第二个从sast-rules
存储库拉取修订版97f7686
,并仅考虑go
子目录中的文件。- 由于出现在配置中较晚,
sast-rules
条目具有更高的优先级。 - 如果两个检出之间存在文件名冲突,则
sast-rules
存储库中的文件会覆盖myrules
存储库中的文件。
- 由于出现在配置中较晚,
- 一个
raw
passthrough,它将其value
写入到/sgrules/insecure.yml
。 - 一个
url
passthrough,它获取一个托管在 URL 上的配置并将其写入到/sgrules/gosec.yml
。
之后,使用位于 /sgrules
下的最终配置调用 Semgrep。
[semgrep]
description = "我的 Semgrep 自定义规则集"
targetdir = "/sgrules"
timeout = 60
[[semgrep.passthrough]]
type = "git"
value = "https://gitlab.com/user/myrules.git"
ref = "develop"
[[semgrep.passthrough]]
type = "git"
value = "https://gitlab.com/gitlab-org/secure/gsoc-sast-vulnerability-rules/playground/sast-rules.git"
ref = "97f7686db058e2141c0806a477c1e04835c4f395"
subdir = "go"
[[semgrep.passthrough]]
type = "raw"
target = "insecure.yml"
value = """
rules:
- id: "insecure"
patterns:
- pattern: "func insecure() {...}"
message: |
Insecure function insecure detected
metadata:
cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
severity: "ERROR"
languages:
- "go"
"""
[[semgrep.passthrough]]
type = "url"
value = "https://semgrep.dev/c/p/gosec"
target = "gosec.yml"
配置 passthrough 链中的模式
您可以选择如何处理 passthrough 链中发生的文件名冲突。默认行为是覆盖具有相同名称的现有文件,但您可以选择 mode = append
来将后续文件的内容附加到之前的文件上。
您可以仅对 file
、url
和 raw
passthrough 类型使用 append
模式。
通过以下自定义规则集配置,两个 raw
passthrough 用于迭代地组装 /sgrules/my-rules.yml
文件,然后将其作为规则集提供给 Semgrep。每个 passthrough 将单个规则附加到规则集。第一个 passthrough 负责根据Semgrep 规则语法初始化顶级 rules
对象。
[semgrep]
description = "我的 Semgrep 自定义规则集"
targetdir = "/sgrules"
validate = true
[[semgrep.passthrough]]
type = "raw"
target = "my-rules.yml"
value = """
rules:
- id: "insecure"
patterns:
- pattern: "func insecure() {...}"
message: |
Insecure function 'insecure' detected
metadata:
cwe: "..."
severity: "ERROR"
languages:
- "go"
"""
[[semgrep.passthrough]]
type = "raw"
mode = "append"
target = "my-rules.yml"
value = """
- id: "secret"
patterns:
- pattern-either:
- pattern: '$MASK = "..."'
- metavariable-regex:
metavariable: "$MASK"
regex: "(password|pass|passwd|pwd|secret|token)"
message: |
Use of hard-coded password
metadata:
cwe: "..."
severity: "ERROR"
languages:
- "go"
"""
# /sgrules/my-rules.yml
rules:
- id: "insecure"
patterns:
- pattern: "func insecure() {...}"
message: |
Insecure function 'insecure' detected
metadata:
cwe: "..."
severity: "ERROR"
languages:
- "go"
- id: "secret"
patterns:
- pattern-either:
- pattern: '$MASK = "..."'
- metavariable-regex:
metavariable: "$MASK"
regex: "(password|pass|passwd|pwd|secret|token)"
message: |
Use of hard-coded password
metadata:
cwe: "..."
severity: "ERROR"
languages:
- "go"
指定私有远程配置
以下示例启用 SAST并使用共享的规则集自定义文件。该文件是:
- 从需要认证的私有项目下载,使用安全存储在 CI 变量中的群组访问令牌。
- 在特定的 Git 提交 SHA 上签出,而不是默认分支。
有关如何找到与群组令牌关联的用户名的信息,请参见群组访问令牌。
include:
- template: Jobs/SAST.gitlab-ci.yml
variables:
SAST_RULESET_GIT_REFERENCE: "group_2504721_bot_7c9311ffb83f2850e794d478ccee36f5:$PERSONAL_ACCESS_TOKEN@gitlab.com/example-group/example-ruleset-project@c8ea7e3ff126987fb4819cc35f2310755511c2ab"